ロギングの目的で、出力の最初の5行だけが必要だとします。また、ログが切り捨てられたかどうか、いつ切り捨てられたかを知る必要があります。
head
を使用してジョブを実行しようとしていますが、以下のseq
コマンドは、head
によって切り捨てられる20行を出力し、echo
は切り捨て情報を出力します:
> seq -f 'log line %.0f' 20 | head -n 5 && echo '...Output truncated. Only showing first 5 lines...'
log line 1
log line 2
log line 3
log line 4
log line 5
...Output truncated. Only showing first 5 lines...
しかし、上記と同じ構成を使用して、seq
コマンドが5行未満を出力すると、間違った「切り捨てられた」ステータスになります。
seq -f ' log line %.0f' 3 | head -n 5 && echo '...Output truncated. Only showing first 5 lines...'
log line 1
log line 2
log line 3
...Output truncated. Only showing first 5 lines...
head
コマンド(または別のツール)が何かを切り捨てたかどうかを通知して、必要な場合にのみ「...切り捨てられた...」メッセージを表示する方法はありますか? ==
警告の注記:
あなたがするとき:
cmd | head
また、出力が切り捨てられた場合、cmd
が終了した後にさらに行を書き込むと、SIGPIPEによってhead
が強制終了される可能性があります。必要なものではない場合、後でcmd
を実行し続けたい場合は、出力が破棄されても、10行が出力された後に終了するのではなく、残りの行を読み取って破棄する必要があります(たとえば、head
の代わりにsed '1,10!d'
またはawk 'NR<=10'
を使用します。
したがって、2つの異なるアプローチの場合:
cmd | awk 'NR>5 {print "TRUNCATED"; exit}; {print}'
cmd | sed '6{s/.*/TRUNCATED/;q;}'
mawk
のawk
実装は、処理を開始する前に入力のバッファフルを蓄積するため、cmd
は、バッファフル(8KiB)を書き込むまで強制終了されない場合があることに注意してください。私のシステムAFAICT)のデータ。これは、-Winteractive
オプションを使用することで回避できます。
一部のsed
実装は、事前に1行を読み取るため($
アドレスを使用するときに、どちらが最後の行であるかを知ることができます)、それらを使用すると、cmd
のみが強制終了されます。 7を出力した後th ライン。
cmd | awk 'NR<=5; NR==6{print "TRUNCATED"}'
cmd | sed '1,6!d;6s/.*/TRUNCATED/'
AWKを使用できます:
seq -f 'line %.0f' 20 | awk 'NR <= 5; NR > 5 { print "...Output truncated. Only showing first 5 lines..."; exit }'
これにより、最初の5行(ある場合)がそのまま印刷されます。それを超える行が見つかった場合は、切り捨てメッセージを出力して終了します。
条件付き処理を実装する場合は、使用する終了コードを指定できます。
seq -f 'line %.0f' 20 | awk 'NR <= 5; NR > 5 { exit 1 }' || echo ...Output truncated. Only showing first 5 lines...