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

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

如何将输出更改为tail使用空终止行而不是换行符?

我的问题与此类似:如何在 bash 中对空分隔输入执行“head”和“tail”?,但不同之处在于我想做类似的事情:

tail -f myFile.txt | xargs -i0 myCmd {} "arg1" "arg2"

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

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

xargs: unmatched double quote;
    by default quotes are special to xargs unless you use the -0 option

答案1

如果你想要最后 10 行:

tail myFile.txt | tr '\n' '\0' | xargs -r0i myCmd {} arg1 arg2

但对于 GNU xargs,您还可以将分隔符设置为换行符:

tail myFile.txt | xargs -ri -d '\n' myCmd {} arg1 arg2

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

可移植的是,您还可以简单地转义每个字符:

tail myFile.txt | sed 's/./\\&/g' | xargs -I{} myCmd {} arg1 arg2

或者引用每一行:

tail myFile.txt | sed 's/"/"\\""/g;s/.*/"&"/' | xargs -I{} myCmd {} arg1 arg2

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

tr '\n\0' '\0\n' < myFile.txt |
  tail |
  tr '\n\0' '\0\n' |
  xargs -r0i myCmd {} arg1 arg2

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

上面的最后一项显然对 没有意义tail -f

一个xargs -d '\n'可以工作,但对于其他的,你会遇到缓冲问题。在:

tail -f myFile.txt | tr '\n' '\0' | xargs -r0i myCmd {} arg1 arg2

tr当它不到达终端(这里是管道)时缓冲它的输出。 IE,它不会写入任何内容,直到它积累了一个完整的缓冲区(大约 8kiB)要写入的数据。这意味着myCmd将被批量调用。

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

tail -f myFile.txt | stdbuf -o0 tr '\n' '\0' |
  xargs -r0i myCmd {} arg1 arg2

相关内容