bashでnull区切りの入力で「head」と「tail」を行う方法は?


18

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

どのようにして行うことができますheadし、tail便利な方法でそれらのヌル区切り入力に?(私はいつでも短くて遅いルビースクリプトを作成できますが、もっと良い方法があるといいのですが)

回答:


21

GNU headおよびtailcoreutilsバージョン8.25以降には、-zそのためのオプションがあります。

古いバージョンでは、非GNUシステムについて、あなたは試してみて、スワップすることができます\0\n

find ... -print0 |
  tr '\0\n' '\n\0' |
  head |
  tr '\0\n' '\n\0'

一部のhead実装ではNUL文字に対応できない(およびPOSIXで必須ではない)ことに注意してください。ただし、findサポート-print0headおよびテキストユーティリティは通常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、a \0は改行文字を意味することに注意してください。だから、例えば、交換する\n_

find . -depth -name $'*\n*' -print0 | nul_terminated sed '
  p;h;s,.*/,,;s/\x0/_/g;H;g;s,[^/]*\n,,' | xargs -r0n2 mv

\x0GNU拡張機能でもあります)。

複数のフィルタリングコマンドを実行する必要がある場合は、次のことができます。

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

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

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

2
これは、値を区切る\x0代わりに使用する主な理由¹を無効にしません\nか?(¹が含まれている可能性のある値に対処できるように\n
Thedward 14年

@Thedwardは、いや、逆に-print0 | tr '\n\0' '\0\n'持ってその中の改行文字がに変換されたファイルのパスを表すを\0。したがって、最初の行をhead -n 1使用して\0sをtr '\0\n' '\n\0'再度改行に変換すると、改行文字が埋め込まれたNUL区切りの最初のファイルパスが得られます。
ステファンシャゼル14年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.