Text-Processing
如何在 bash 中對以空分隔的輸入執行“head”和“tail”?
find
命令可以將文件名輸出為空分隔的字元串(如果-print0
提供),並且可以在打開選項的xargs
情況下使用它們。-0
但在這兩者之間,很難操縱文件的集合——sort
命令有-z
開關,可以對這些文件進行排序,但head
沒有tail
它們。我怎樣才能以方便
head
的tail
方式對那些以空分隔的輸入進行操作?(我總是可以創建一個短而慢的 ruby 腳本,但我希望有更好的方法)
GNU
head
和tail
自 coreutils 8.25 版以來都有一個-z
選項。對於舊版本或非 GNU 系統,您可以嘗試交換
\0
和\n
:find ... -print0 | tr '\0\n' '\n\0' | head | tr '\0\n' '\n\0'
請注意,某些
head
實現無法處理 NUL 字元(POSIX 不需要它們),但是 find 支持-print0
和head
文本實用程序通常支持 NUL 字元。您還可以使用函式將任何命令包裝在兩個
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
,a\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 ...