Rog*_*ach 19 find xargs tail text-processing head
find
命令可以将文件名输出为空分隔的字符串(如果-print0
提供),并且xargs
可以在-0
打开选项的情况下使用它们。但是在两者之间,很难对文件进行操作的该集合-sort
命令有-z
开关,这使得它可能对这些文件进行排序,但head
并tail
没有他们。
我该怎么做head
,并tail
在一个方便的方式与空分隔的投入?(我总是可以创建一个简短而缓慢的 ruby 脚本,但我希望可以有更好的方法)
Sté*_*las 22
GNUhead
和tail
因为 coreutils 版本 8.25 有一个-z
选项。
对于旧版本或非 GNU 系统,您可以尝试交换\0
和\n
:
find ... -print0 |
tr '\0\n' '\n\0' |
head |
tr '\0\n' '\n\0'
Run Code Online (Sandbox Code Playgroud)
请注意,有些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 ...
Run Code Online (Sandbox Code Playgroud)
请记住,在 下nul_terminated
,a\0
表示换行符。例如,替换\n
为_
:
find . -depth -name $'*\n*' -print0 | nul_terminated sed '
p;h;s,.*/,,;s/\x0/_/g;H;g;s,[^/]*\n,,' | xargs -r0n2 mv
Run Code Online (Sandbox Code Playgroud)
(\x0
也是 GNU 扩展)。
如果您需要运行多个过滤命令,您可以执行以下操作:
find ... -print0 |
nul_terminated cmd1 |
nul_terminated cmd2 | xargs -r0 ...
Run Code Online (Sandbox Code Playgroud)
但这意味着运行一些冗余tr
命令。或者,您可以运行:
find ... -print0 | nul_terminated eval 'cmd1 | cmd2' | xargs -r0 ...
Run Code Online (Sandbox Code Playgroud)