同じ2つのフィールドを持つ行を見つけ、それらの1つを除いてすべてを削除する方法[重複]

同じ2つのフィールドを持つ行を見つけ、それらの1つを除いてすべてを削除する方法[重複]

この質問をいろいろな部分に分ければ簡単になると思います。

  1. 最初のフィールドの値が同じで、最後のフィールドの値が同じ行を見つける方法はありますか? - しかし、必ずしも同じである必要はありませんか?

ライン:

  AAAAA stuff in between BBBBB
  AAAAA more stuff in the middle CCCCCC
  AAAAA even more cool stuff BBBBB

興味のあるライン:

  AAAAA stuff in between BBBBB
  AAAAA even more cool stuff BBBBB
  1. 同じ最初のフィールドと最後のフィールドが重複する行を除くすべての行を削除する方法はありますか?

今後:

  AAAAA stuff in between BBBBB
  AAAAA more stuff in the middle CCCCCC
  AAAAA even more cool stuff BBBBB

後ろに:

  AAAAA stuff in between BBBBB
  AAAAA more stuff in the middle CCCCCC

ソリューションを簡素化するために、ファイルを少し操作できます(たとえば、固定数のフィールドの設定など)。

現在のファイルには1行あたりのフィールド数が異なりますが、最初のフィールドと最後のフィールドが重要です。

すべてのフィールドの間にスペースがあります。

私はawkへのいくつかの参照を検索して見つけましたが、この方法で複数のフィールドを使用するawkの例が見つかりませんでした。

とても感謝しています。

ベストアンサー1

GNUAWK

以下は、わずかに変更された入力ファイルを使用したテストの実行です。

bash-4.3$ $ awk '{v=sprintf("%s_%s",$1,$NF); if ( ! a[v]) print;   a[v]++;   }' input.txt 
bash: $: command not found
bash-4.3$ awk '{v=sprintf("%s_%s",$1,$NF); if ( ! a[v]) print;   a[v]++;   }' input.txt 
AAAAA stuff in between BBBBB
AA stuff AAABBBBB
AAAAA more stuff in the middle CCCCCC

bash-4.3$ cat input.txt
AAAAA stuff in between BBBBB
AA stuff AAABBBBB
AAAAA more stuff in the middle CCCCCC
AAAAA even more cool stuff BBBBB
AAAAA extra line CCCCCC

動作原理:

  • 要点:キーと値のペアの配列を作成し、キーと値のペアの配列項目が既に存在するかどうかに基づいて印刷します。
  • キーは行の最後のフィールドv=sprintf("%s_%s",$1,$NF)で構成されます$NF。たとえば、行1と3の場合、キーはですAAAAABBBBB。値は一致するたびに増加する整数です。
  • v各行で変数とそのチェックを実行しif (!a[v]) print、配列に値が見つからない場合にのみ印刷します。
  • a[v]++印刷するかどうかに関係なく、すべての行で実行されます

Sundeepがコメントで指摘したように、同じアプローチを次のように単純化できます。

bash-4.3$ awk '!seen[$1"_"$NF]++' input.txt
AAAAA stuff in between BBBBB
AA stuff AAABBBBB
AAAAA more stuff in the middle CCCCCC

おすすめ記事