在 bash 管道中使用流处理处理连续的单行数据?

在 bash 管道中使用流处理处理连续的单行数据?

我正在调试一个嵌入式服务器,该服务器将连续的单行文本输出到指定的网络端口。流中的任何位置都没有换行符,但它是文本数据,我想在输出时对其进行格式化。我尝试使用 tr (翻译)将流中的字符交换为有效的换行符,但是不可能找到始终可以被换行符明智地替换的唯一单个字符。我最初的想法是使用 sed 将换行符添加到 2-3 个字符的模式中,但因为 sed 是基于行的,并且流是永无止境的单行,所以 sed 将永远不会完成该过程!是否有基于非行的 sed 替代方案?

答案1

这就是fold目的:

NAME
       fold - wrap each input line to fit in specified width

SYNOPSIS
       fold [OPTION]... [FILE]...

DESCRIPTION
       Wrap input lines in each FILE, writing to standard output.

       With no FILE, or when FILE is -, read standard input.

       Mandatory  arguments  to  long options are mandatory for short options
       too.

       -b, --bytes
              count bytes rather than columns

       -s, --spaces
              break at spaces

       -w, --width=WIDTH
              use WIDTH columns instead of 80

       --help display this help and exit

       --version
              output version information and exit

正如您在上面看到的,它可以根据宽度折叠行,这样您就可以得到 100 个字符的行:

command_that_reads_from_port | fold -w 100

这是一个标准程序,是 GNU coreutils 的一部分,因此它应该存在于任何 GNU 系统上。

答案2

解决方案如下

stdbuf -o0 ncat -ul 51002 | stdbuf -o0 fold | sed "s/\[15/\&\[15/g" -u | stdbuf -o0 tr -d '\n' | tr "&" "\n"

其中 [15 是我想要在其前面添加换行符的模式。有点解决办法,但效果很好。

答案3

从您发布的答案来看,这听起来可能就是您所需要的,使用 GNU awk 进行多字符 RS 和 RT:

$ printf '%s' 'foo[15bar[15and stuff' |
    awk -v RS='[[]15' '{print pRT $0; pRT=RT}'
foo
[15bar
[15and stuff

但没有样本输入/输出,这是一个猜测。您可以在 awk 脚本内对您喜欢的数据进行任何处理,和/或者如果您希望它在一定数量的[15分隔记录或一定数量的字符之后停止处理数据,您可以简单地添加计数并退出,例如20 条记录后退出:

awk -v RS='[[]15' '{print pRT $0; pRT=RT} NR==20{exit}'

或 1000 个字符后:

awk -v RS='[[]15' '{$0=pRT $0; n+=length(); print; pRT=RT} n==1000{exit}'

或者任何你喜欢的东西。

根据需要添加 stdbuf 部分。

相关内容