次のタブで区切られたテーブルがあります。
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記号で表示し、その***
マークで始まるレコードがここに表示されます。