列2が列1の2つ以上の値に対応する場合は、すべての行を削除します。

列2が列1の2つ以上の値に対応する場合は、すべての行を削除します。

次のタブで区切られたテーブルがあります。

GL89     AADAC
GL89     AFGAC
GL89     AFDAC
GL50     AC923
GL50     AC923
GL79     AC923
GL99     AC923
GL99     AC923
GL60     AC100
GL60     AC100
GL20     AC200
GL30     AC300
GL30     AC400

2列の値の1つ以上が1列の2つ以上の値に対応する行を削除したい場合は、この場合は次の行を削除する必要があります。

GL50     AC923
GL79     AC923
GL99     AC923
GL99     AC923

残りのテーブルは維持してください。

GL89     AADAC
GL89     AFGAC
GL89     AFDAC
GL60     AC100
GL60     AC100
GL20     AC200
GL30     AC300
GL30     AC400

フォームがありますか?ありがとうございます!

ベストアンサー1

awk 'BEGIN{ FS=OFS="\t" }
{ data[$2]= (data[$2]==""?"":(k[$2]==$1? data[$2] ORS: "@") ) $0; k[$2]=$1 }

END{ for(x in data) if(data[x] !~/^@/) print data[x] }' infile

注:印刷時に印刷しないレコードを表示するために文字を使用しているため、@この文字は入力ファイルではありません。それ以外の場合は別のものに変更する必要があります(または次の文字セットを選択してください)。代わりに文字列)。

  • data[$2]= (data[$2]==""?"":(XXX) ) $0、配列が空でない場合は、そのセクションのdata結果として配列値を更新し、現在の行を追加します。(XXX)この列は$2配列キーとして使用されます。

  • (XXX)(k[$2]==$1? data[$2] ORS: "@")同じキーの値(キーの最新の値のペアを維持するために配列をヘルパーとして使用)が異なる場合は、atシンボル文字が設定され、それ以外の場合はキーにt内容+改行文字(ORS)が追加されます。 )。

  • @最後に、2番目の列は同じですが、最初の列が1つ以上の他のすべての行は、コード内の特定の文字でマークされているため削除されます。


コードをよりよく理解するために、print ...いつでもこのステートメントを使用して何が起こっているのかを確認できます。

awk 'BEGIN{ FS=OFS="\t" }
{ data[$2]= (data[$2]==""?"":(k[$2]==$1? data[$2] ORS: "***") ) $0; k[$2]=$1 }

END{ for(x in data) print "<" data[x] ">" }' infile

元のコマンドから削除されたレコードをat記号で表示し、その***マークで始まるレコードがここに表示されます。

おすすめ記事