使用 tail 时将换行符转换为空分隔符

Lar*_*ars 21 xargs tail text-processing

如何将输出更改tail为使用以空字符结尾的行而不是换行符?

我的问题类似于这个问题:如何在 bash 中对空分隔输入执行 `head` 和 `tail`?,但不同之处在于我想做一些类似的事情:

tail -f myFile.txt | xargs -i0 myCmd {} "arg1" "arg2"
Run Code Online (Sandbox Code Playgroud)

我没有使用find,所以不能使用-print0

这一切都是为了避免xargs中出现的错误:

xargs: unmatched double quote;
    by default quotes are special to xargs unless you use the -0 option
Run Code Online (Sandbox Code Playgroud)

Sté*_*las 31

如果你想要最后 10 行:

tail myFile.txt | tr '\n' '\0' | xargs -r0i myCmd {} arg1 arg2
Run Code Online (Sandbox Code Playgroud)

但是使用 GNU xargs,您还可以将分隔符设置为换行符:

tail myFile.txt | xargs -ri -d '\n' myCmd {} arg1 arg2
Run Code Online (Sandbox Code Playgroud)

-0是 的缩写-d '\0')。

便携,您也可以简单地转义每个字符:

tail myFile.txt | sed 's/./\\&/g' | xargs -I{} myCmd {} arg1 arg2
Run Code Online (Sandbox Code Playgroud)

或引用每一行:

tail myFile.txt | sed 's/"/"\\""/g;s/.*/"&"/' | xargs -I{} myCmd {} arg1 arg2
Run Code Online (Sandbox Code Playgroud)

如果您想要最后 10 条以 NUL 分隔的记录myFile.txt(但那不会是文本文件),则\n必须\0在调用之前将tail其转换为,这意味着必须完全读取文件:

tr '\n\0' '\0\n' < myFile.txt |
  tail |
  tr '\n\0' '\0\n' |
  xargs -r0i myCmd {} arg1 arg2
Run Code Online (Sandbox Code Playgroud)

编辑(因为您在问题中更改了tailto tail -f):

上面的最后一个显然对tail -f.

xargs -d '\n'一会工夫,但对于其他的人,你就会有一个缓冲的问题。在:

tail -f myFile.txt | tr '\n' '\0' | xargs -r0i myCmd {} arg1 arg2
Run Code Online (Sandbox Code Playgroud)

tr当它没有进入终端(这里是一个管道)时缓冲它的输出。IE,它不会写任何东西,直到它积累了一个缓冲区(比如 8kiB)要写入的数据。这意味着myCmd将分批调用。

在 GNU 或 FreeBSD 系统上,您可以tr使用以下stdbuf命令更改缓冲行为:

tail -f myFile.txt | stdbuf -o0 tr '\n' '\0' |
  xargs -r0i myCmd {} arg1 arg2
Run Code Online (Sandbox Code Playgroud)