bashでアンチジョインまたはインバースジョインを行う方法

一部のデータ分析ソフトウェアがアンチジョインと呼ぶものを実行したい:これらの行を1つのリストから削除する別のリストの一致する行。おもちゃのデータと期待される出力は次のとおりです。

$ echo -e "a\nb\nc\nd" > list1 $ echo -e "c\nd\ne\nf" > list2 $ antijoincommand list1 list2 a b 

コメント

  • 関連 unix.stackexchange.com/q/11343/117549
  • これはあなたの質問に答えますか? あるファイルの行を別のファイルにない行を取得するツールはありますか?
  • @Muru、はい、その投稿は解決策を提供しますTerdon 'の回答に示されています。ただし、" bash anti-join "(この種のプロセスに関連する用語)を検索したときは、'何か役に立つものは見つかりません。私のOP(他の人が編集した)は、この質問をする際の私の明確な目的は、用語" anti-join "を関連付けることであると述べましたこの用語を検索すると、これらのソリューションが得られます。ありがとう。

回答

joinは使用しませんこれは、joinでは入力を並べ替える必要があるためです。これは、このような単純なジョブでは不要な複雑さです。代わりにgrepを使用できます:

$ grep -vxFf list2 list1 a b 

またはawk

$ awk "NR==FNR{++a[$0]} !a[$0]" list2 list1 a b 

ファイルがすでに並べ替えられている場合、join -v 1の代わりにcomm -23

$ comm -23 list1 list2 a b 

コメント

  • grepsortを回避するのは素晴らしいことです私が提供したおもちゃのデータに感謝します。ありがとう!現実の世界では、私のfile1には複数のデータ列があり、そのうちの1つが結合に使用されています。awkの修正バージョンコードはこのユースケースに対応します。
  • @Joshはい、$0$Nに変更します。 Nは、参加するフィールド番号です。
  • これは、file1とfile2の列番号が異なっていても機能します:awk NR == FNR {++ a [$ 2]}!a [$ 5] ' list2 list1;タグファイルがメインデータとは異なる形式であるのはごく普通のことです。

回答

次の方法の1つjoinユーティリティでこれを行うには次のようにします。

$ join -v 1 list1 list2 a b 

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です