web-dev-qa-db-ja.com

X行の後に出力を切り捨て、出力が切り捨てられた場合にのみメッセージを出力します

ロギングの目的で、出力の最初の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コマンド(または別のツール)が何かを切り捨てたかどうかを通知して、必要な場合にのみ「...切り捨てられた...」メッセージを表示する方法はありますか? ==

6
Gohu

警告の注記:

あなたがするとき:

cmd | head

また、出力が切り捨てられた場合、cmdが終了した後にさらに行を書き込むと、SIGPIPEによってheadが強制終了される可能性があります。必要なものではない場合、後でcmdを実行し続けたい場合は、出力が破棄されても、10行が出力された後に終了するのではなく、残りの行を読み取って破棄する必要があります(たとえば、headの代わりにsed '1,10!d'またはawk 'NR<=10'を使用します。

したがって、2つの異なるアプローチの場合:

出力が切り捨てられ、cmdが強制終了される可能性があります

cmd | awk 'NR>5 {print "TRUNCATED"; exit}; {print}'
cmd | sed  '6{s/.*/TRUNCATED/;q;}'

mawkawk実装は、処理を開始する前に入力のバッファフルを蓄積するため、cmdは、バッファフル(8KiB)を書き込むまで強制終了されない場合があることに注意してください。私のシステムAFAICT)のデータ。これは、-Winteractiveオプションを使用することで回避できます。

一部のsed実装は、事前に1行を読み取るため($アドレスを使用するときに、どちらが最後の行であるかを知ることができます)、それらを使用すると、cmdのみが強制終了されます。 7を出力した後th ライン。

出力は切り捨てられ、残りは破棄されるため、cmdは強制終了されません

cmd | awk 'NR<=5; NR==6{print "TRUNCATED"}'
cmd | sed '1,6!d;6s/.*/TRUNCATED/'
12

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...
6
Stephen Kitt