
フラット ファイル A と B が 2 つあります。A は数百万件のレコードを持つ大きなファイルで、B は A のサブセットであるはずです。A には 1 つの一意のキーを持つ 20 の列があり、B には同じ一意のキーを持つ 5 つの列があります。B と A を比較して、ファイル B にあるレコードがファイル A にも存在し、それぞれの列に同じデータがあるかどうかを確認する方法を教えてください。
答え1
コマンドを説明するために2つのファイルを作成しました
file1
:
1 a1 b1 c1 d1 e1
2 a2 b2 c2 d2 e2
3 a3 b3 c3 d3 e3
4 a4 b4 c4 d4 e4
5 a5 b5 c5 d5 e5
file2
:
2 b2 c2 e2
4 b4 c4 xx
5 b5 c5 e5
最初の列は一意のキーです。共通の列はb
、列 、c
および ですe
。共通の行は2
、、4
および です5
。行 の4
列 には異なる値がありますe
。
出力付きのコマンドは次のとおりです。
$ comm -1 -3 <(cut -d' ' -f1,3,4,6 file1) file2
4 b4 c4 xx
ファイルがまだソートされていない場合は、次のようにします。
$ comm -1 -3 <(cut -d' ' -f1,3,4,6 file1 | sort) <(sort file2)
説明:
cut -d' ' -f1,3,4,6 file1
ファイルからフィールド番号 1、3、4、6 を出力します。フィールドはスペースで区切られます。フィールドがコンマで区切られている場合は、cut
次のように使用します。cut -d','
<( ... )
comm -1 -3 file1 file2
ファイル2に固有の行を出力します。
注意:
cut
区切り文字がフィールド内の文字として出現する可能性がある場合には問題が発生します。
例えば:
"field1","field2,stillfield2","field3"
cut
内のカンマが"field2,stillfield2"
フィールドの一部であることを理解できません。
もしあなたのファイルがそのようなものなら、CSV処理が組み込まれたプログラミング言語を使う方が良いかもしれません。例えばパイソン。
答え2
あなたがおっしゃるように、ファイルに異なる列がある場合、最も簡単な方法は、選択した言語を使用して小さなプログラムを作成することです。ファイル内の行構造が同一でない場合diff
、comm
あまり役に立ちません。
答え3
comm
およびソリューションとは別に、これに対してdiff
使用できるものがあります。 関連データがファイル A の列 1、3、10、ファイル B の列 1、2、3 であると仮定します。Aから列を選択するために、これをキーワード一致ファイルとして使用し、ファイル B での存在を逆チェックします。ファイル B に、ファイル A から抽出された一致行に存在しない行がある場合、それらが表示されます。すべて一致する場合、出力はありません (B は A のサブセットであると考えられるため)grep
cut
grep -wvf <( cut -f1,3,10 fileA ) fileB
または、ファイル B に 3 つ以上の列がある場合:
grep -wvf <( cut -f1,3,10 fileA ) <( cut -f1,2,3 fileB )