web-dev-qa-db-ja.com

末尾を使用するときに改行をヌル区切りに変換する

改行の代わりにnullで終了する行を使用するようにtailからの出力を変更するにはどうすればよいですか?

私の質問はこれと似ています: bashでヌル区切りの入力で `head`と` tail`を行う方法? ですが、次のようなことをしたいという点で異なります:

tail -f myFile.txt | xargs -i0 myCmd {} "arg1" "arg2"

findを使用していないため、-print0を使用できません

これはすべて、xargsで発生するエラーを回避するためです。

xargs: unmatched double quote;
    by default quotes are special to xargs unless you use the -0 option
20
Lars

最後の10行が必要な場合:

tail myFile.txt | tr '\n' '\0' | xargs -r0i myCmd {} arg1 arg2

ただし、GNU xargsを使用すると、区切り文字を改行に設定することもできます。

tail myFile.txt | xargs -ri -d '\n' myCmd {} arg1 arg2

-0-d '\0'の略です)。

移植性があり、すべての文字を単純にエスケープすることもできます。

tail myFile.txt | sed 's/./\\&/g' | xargs -I{} myCmd {} arg1 arg2

または各行を引用します:

tail myFile.txt | sed 's/"/"\\""/g;s/.*/"&"/' | xargs -I{} myCmd {} arg1 arg2

myFile.txtのNUL区切りの最後の10個のレコードが必要な場合(ただし、それはテキストファイルではありません)、tailを呼び出す前に\n\0に変換する必要があります。これは、ファイルを完全に読み取る必要があることを意味します。

tr '\n\0' '\0\n' < myFile.txt |
  tail |
  tr '\n\0' '\0\n' |
  xargs -r0i myCmd {} arg1 arg2

編集(質問でtailtail -fに変更したため):

上記の最後のものは、tail -fでは明らかに意味がありません。

xargs -d '\n'の1つは機能しますが、他の1つではバッファリングの問題が発生します。に:

tail -f myFile.txt | tr '\n' '\0' | xargs -r0i myCmd {} arg1 arg2

trは、ターミナル(ここではパイプ)に移動しないときに出力をバッファーに入れます。つまり、書き込むデータのバッファーがいっぱい(8kiBのようなもの)になるまで、何も書き込みません。つまり、myCmdがバッチで呼び出されます。

GNUまたはFreeBSDシステムでは、trコマンドを使用してstdbufのバッファリング動作を変更できます。

tail -f myFile.txt | stdbuf -o0 tr '\n' '\0' |
  xargs -r0i myCmd {} arg1 arg2
26