web-dev-qa-db-ja.com

bashでnullで区切られた入力で `head`と` tail`を行う方法は?

findコマンドはファイルの名前をnull区切りの文字列として出力でき(-print0が指定されている場合)、xargs-0オプションをオンにしてファイルを使用できます。しかし、その間に、ファイルのコレクションを操作するのは困難です-sortコマンドには-zスイッチがあり、これらのファイルを並べ替えることができますが、headtailそれらを持っていません。

これらのnull区切りの入力に対して、便利な方法でheadおよびtailを実行するにはどうすればよいですか? (私はいつでも短くて遅いRubyスクリプトを作成できますが、もっと良い方法があることを願っています)

18
Rogach

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が-print0headをサポートし、テキストユーティリティが一般的にサポートしていることに注意してくださいNUL文字。

関数を使用して、2つの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拡張子)です。

複数のfilteringコマンドを実行する必要がある場合は、次の操作を実行できます。

find ... -print0 |
  nul_terminated cmd1 |
  nul_terminated cmd2 | xargs -r0 ...

しかし、それはいくつかの冗長なtrコマンドを実行することを意味します。または、次を実行することもできます。

find ... -print0 | nul_terminated eval 'cmd1 | cmd2' | xargs -r0 ...
21