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