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)