Linuxでは、抽出行が連続して3回以上表示されます。

Linuxでは、抽出行が連続して3回以上表示されます。

Linuxにはテーブルがあります。

A 0
A 0
A 0
B 0
B 1
B 0
B 1
B 0

連続して3回以上現れる行を抽出したいと思います。

私の予想結果は次のとおりです。

A 0

実際、3回以上は単なる例に過ぎません。実際の状況は、連続して30回以上現れる行を抽出したいことです。

どんなアイデアがありますか?

ありがとうございます!

答え1

uniq -c file | awk '$1 >= 3 { print $2,$3 }'

uniq -c各行は、その行の連続発生回数とともに出力されます。与えられたデータについて

   3 A 0
   1 B 0
   1 B 1
   1 B 0
   1 B 1
   1 B 0

awk最初のフィールドが3以上の場合、スクリプトはこの値を使用して最後の2つのフィールドを出力します。

結果は次のとおりです。

A 0

答え2

簡単なものはawk次のように使用できます。

awk '{!s[$0]++} END{for (x in s) if (s[x]>2) print x}' infile

2回以上繰り返されるが>2全体的に繰り返される行を印刷します。>29ラインが≥30回繰り返されるように設定できます。

@Philipposが指摘したように、次のコマンドを使用して3回以上繰り返される連続行のみを印刷できます。

awk 'p!=$0{n=0} {p=$0;n++} (n==3)'

説明: 前の行を に保存しp、 の行数を計算しn、行が前の行と異なる場合はカウンターをリセットします。3回目または30回目)が発生したときに印刷します。


あるいは、同じ効果を得るための短い方法もあります。

awk 'p!=$0{n=0;p=$0} ++n==3'

答え3

sed純粋なバージョンが欠けています!これを行うことができます:

sed 'x;G;s/\(.*\)\n\1$/+\1/;/\n/d;h;s/^+\{2\}//;/^+/d' file

2を連続30行に変更します29。これが何とか最適化できるかどうか疑問に思います。

仕組み:予約されたスペースでは、前の行が維持され、その行+がさらに発生するたびに引出線が追加されます。各行ごとにxバッファーが置き換えられるため、現在の行は予約済みスペースにあります。スペースはさらにG予約されているため、パターンスペースには新しい行で区切られた古い行と新しい行があります。改行の前後に行が表示されると、2つの同じ行があり、このsコマンドは行の1つと改行を置き換えます+。パターンにまだ改行がある場合は、行が異なるため、開始できます。新しいループ(/\n/d)。それ以外の場合は、変更された行を収集用に予約済みスペースにコピーします+。最後に、必要+な行数(1行を除く)を削除します。それでも先行行がある場合は、多すぎる+か足りない行を収集してd削除します。

答え4

シングルアッスクリプト:

awk '{k=$1 FS $2}!a[k] || (NR==n && k==pk){ a[k]++; pk=k; n=NR+1 }
     END{ for(i in a) if(a[i] >=3) print i }' file

  • k=$1 FS $2- キーキー、最初と2番目のフィールドの接続

  • !a[k] || (NR==n && k==pk)- 記録が初めて発生するか、以前の記録と同時に発生するかを確認する


出力:

A 0

関連情報