

【内容】  
コマンドにて、「IDを列挙しているファイル」と、「IDなどが記述されているcsv」を比較し  
csvから、「IDを列挙しているファイル」に記載されていないIDのレコードを抽出したいです。

【例】  
IDを列挙しているファイル（hogehoge_list）

[code]

    AAAAAA
    XXXXXX
    ZZZZZZ
    
[/code]

IDなど様々な情報が記述されているcsv(foofoo.csv)

[code]

    AAAAAA,タイトル,URL
    BBBBBB,タイトル,URL
    XXXXXX,タイトル,URL
    ZZZZZZ,タイトル,URL
    
[/code]

「hogehoge_list」と「foofoo.csv」を比較して、「hogehoge_list」にないIDである『BBBBBB』の「foofoo.csv」の行を取得したい。

[code]

    BBBBBB,タイトル,URL
    
[/code]

よろしくお願いします。


CC BY-SA 4.0
2018-10-27T14:47:14.927
49711
2018-10-28T23:32:31.993
30723
question
linux bash shellscript shell grep
コマンドでファイル比較し、一致しないレコードを抽出する方法

[code]

    join -t',' -v2 hogehoge_list foofoo.csv
    
[/code]

[`join`](https://linuxjm.osdn.jp/html/GNU_coreutils/man1/join.1.html) コマンドの
`-v` オプションを利用し、一列目で結合されなかった `foofoo.csv` の行のみを出力しています。両ファイルとも対象の列で
**ソートされている必要** があります。

ソートなども含めて書くと、例えば以下のようになります。

[code]

    #!/bin/sh
    
    # エラーで即時終了, > (リダイレクト)による上書き禁止
    set -eC
    
    # join コマンドのため、少なくとも一列目はソートされている必要がある
    LC_ALL=C sort hogehoge_list -t',' >delete_ids.txt
    LC_ALL=C sort foofoo.csv -t',' >all.csv
    
    LC_ALL=C join -t',' -v2 delete_ids.txt all.csv >out.csv
    
[/code]


CC BY-SA 4.0
2018-10-28T10:18:07.067
49730
2018-10-28T10:24:05.550
2018-10-28T10:24:05.550
3054
3054
49711
answer


AWK でもよろしければ、次の one-liner はいかがでしょうか。

[code]

    awk -F, 'FNR==NR{a[$1]++; next} !a[$1]' hogehoge_list foofoo.csv
    
[/code]

  * `-F,` でフィールドセパレーターを "," に設定します
  * `FNR`が `NR` に等しい時、つまり最初のファイル `hogehoge_list` が読まれている間は `{...}` 内の処理が実行されます。ここで `hogehoge_list` 内のIDが連想配列に蓄えられます
  * 2番目のファイル `foofoo.csv` が読まれている間は次の `!a[$1]` が処理されます。つまり`hogehoge_list` に含まれていない時のみ、デフォルト動作である `print` が実行されます

AWKで複数のファイルを処理する際の定番ですが、ご参考まで。


CC BY-SA 4.0
2018-10-28T23:32:31.993
49742
2018-10-28T23:32:31.993
25106
49711
answer