n本以上のラインがある場合のみパイプ出力

n本以上のラインがある場合のみパイプ出力

私はしばしばいくつかのヘッダ行を含むプロセスの出力を知りたいと思います。ただし、grepが実際のコンテンツ行をすべて削除する場合は、ヘッダー行を表示したくありません。これを行うにはthisに似たコマンドが必要ですtailが、n行を返すのではなく次のものを返します。みんな行(タイトル)がn個以上の場合にのみ適用されます。

同僚はこれを行うために小さなPythonツールを作成しましたが、これを行うために必要なすべてのコンピュータにそれをインストールする必要があります。

標準ツール(おそらくawk?)を使用してこの効果を得るための短いコマンドラインはありますか?

答え1

awk 配列の最初の行を保存nし、line が表示されたときn + 1、つまり少なくとも 1 行のデータが見つかったときに書き込むことができます。

Awk_N='
FNR <= N { X[FNR] = $0; next; }
FNR == N + 1 {
    for (j = 1; j in X; ++j) print X[j];
    delete X;
}
{ print; }
'

awk -v N=7 "${Awk_N}"

7Awk部分を編集せずに置き換えることができるように、シェル空間変数を作成しました。

Awk部分は、パイプラインを整理するために一重引用符で囲まれた複数行のシェル文字列変数として事前に宣言されています。

awkgrepロジックをここに含めることができるかどうかを検討することもできます。

少し短いバージョンですべての行を保存します。

awk '{ X[NR] = $0 } END { if (NR > 3) for (j = 1; j in X; ++j) print X[j] }'

これにより、文字数が最小限に抑えられます(読みやすさが低下します)。

awk '{X[NR]=$0}END{if(NR>3)for(j=1;j in X;++j)print X[j]}'

答え2

以下は1行ですsed(すべての内容を印刷すると仮定し、少なくとも4行がある場合n=4)。

cmd | sed -e '4,$!{H;1h;d;}' -e '4H;4x'

したがって、変数を使用したい場合

cmd | sed -e "${n}"',$!{H;1h;d;}' -e "${n}H;${n}x"

これは、前のバッファn-1の最初の行を保存してパターン空間から削除するため、何も印刷されないことです。パターンスペースに行が含まれています。残りは自動印刷の問題です。 GNU以外の設定では、次のように書くことがあります(今回は前提):HdsednHx1n
n=21

cmd | sed '21,$!{
H;1h;d
}
21H;21x'

答え3

ヘッダー長が7行の場合、入力長が<= 7の場合は削除できます。 Perlまたは(gnu)sedを使用してください。

cmd... | perl -0pe 's/^(.*\n){,7}$//'
cmd... | sed   -zE 's/^(.*\n){,7}$//m'

(ギガバイト入力でこれを実行しないでください)

答え4

tee私は以下を使ってこの問題を解決しましたwc

cmd | tee x | [ `wc -l <&0` -gt 3 ] && cat x && rm x

この例では、3行以上の場合、出力全体が印刷されます。

NB1行が3つ以上であるかどうかを知る必要がある場合、ファイル全体の行数を数えるのは過剰です。

NB2はパフォーマンスをさらに低下させ、一時ファイルに書き込みます。私が理解しているように、私はmkfifoメモリに保存されますが、コマンドは長くなります。

関連情報