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字符。
您还可以使用函数在两个tr
s 之间包装任何命令:
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
并将\0
s tr '\0\n' '\n\0'
再次转换为换行,则您将获得第一个文件路径NUL分隔,其中包含嵌入的换行符。
\x0
而不是限制\n
值的主要理由吗?(¹这样您就可以应对可能包含的值\n
)