Answers:
GNU head以及tail从coreutils版本8.25开始都有一个-z选项。
对于较旧的版本或非GNU系统,您可以尝试交换\0和\n:
find ... -print0 |
tr '\0\n' '\n\0' |
head |
tr '\0\n' '\n\0'
请注意,有些head实现不能NULL字符处理(和他们不是POSIX要求),但在那里找到支持-print0,head并文本实用程序通常支持NULL字符。
您还可以使用函数在两个trs 之间包装任何命令:
nul_terminated() {
tr '\0\n' '\n\0' | "$@" | tr '\0\n' '\n\0'
}
find ... -print0 | nul_terminated tail -n 12 | xargs -r0 ...
请记住,在下nul_terminated,\0表示换行符。因此,例如,替换\n为_:
find . -depth -name $'*\n*' -print0 | nul_terminated sed '
p;h;s,.*/,,;s/\x0/_/g;H;g;s,[^/]*\n,,' | xargs -r0n2 mv
(\x0也是GNU扩展)。
如果您需要运行多个过滤命令,则可以执行以下操作:
find ... -print0 |
nul_terminated cmd1 |
nul_terminated cmd2 | xargs -r0 ...
但这意味着要运行一些冗余tr命令。或者,您可以运行:
find ... -print0 | nul_terminated eval 'cmd1 | cmd2' | xargs -r0 ...
-print0 | tr '\n\0' '\0\n'具有线表示其中在它们换行字符已被转换到该文件的路径\0。因此,如果您使用的第一行head -n 1并将\0s tr '\0\n' '\n\0'再次转换为换行,则您将获得第一个文件路径NUL分隔,其中包含嵌入的换行符。
\x0而不是限制\n值的主要理由吗?(¹这样您就可以应对可能包含的值\n)