find
コマンドはファイルの名前をnull区切りの文字列として出力でき(-print0
が指定されている場合)、xargs
は-0
オプションをオンにしてファイルを使用できます。しかし、その間に、ファイルのコレクションを操作するのは困難です-sort
コマンドには-z
スイッチがあり、これらのファイルを並べ替えることができますが、head
とtail
それらを持っていません。
これらのnull区切りの入力に対して、便利な方法でhead
およびtail
を実行するにはどうすればよいですか? (私はいつでも短くて遅いRubyスクリプトを作成できますが、もっと良い方法があることを願っています)
Coreutilsバージョン8.25にはそのための-z
オプションがあるため、GNU head
およびtail
。
古いバージョンまたは非GNUシステムの場合は、\0
と\n
を交換してみてください。
find ... -print0 |
tr '\0\n' '\n\0' |
head |
tr '\0\n' '\n\0'
一部のhead
実装はNUL文字を処理できません(POSIXでは必要ありません)が、findが-print0
、head
をサポートし、テキストユーティリティが一般的にサポートしていることに注意してくださいNUL文字。
関数を使用して、2つの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拡張子)です。
複数のfilteringコマンドを実行する必要がある場合は、次の操作を実行できます。
find ... -print0 |
nul_terminated cmd1 |
nul_terminated cmd2 | xargs -r0 ...
しかし、それはいくつかの冗長なtr
コマンドを実行することを意味します。または、次を実行することもできます。
find ... -print0 | nul_terminated eval 'cmd1 | cmd2' | xargs -r0 ...