次の2つのcsvファイルが提供されています(以前にソートされています)。
ファイル1
a,1,val1
b,2,val2
c,3,val3
d,4,val4
e,5,val5
f,6,val6
g,7,val7
ファイル2
a,1,val1
b,2,val2
c,3,val3x
e,5,val5x
g,7,val7
h,8,val8
3番目の列の値が変更された行のみを比較してインポートするにはどうすればよいですか?私は次のようなものを得ることを期待しています:
c,3,val3x
e,5,val5x
同じ行、追加、または削除された行は無視する必要があり、変更された行にのみ興味があります。私はPearl、Pythonなどの代わりにLinuxの基本コマンドを使用することを好みます。会社は何千万行ものファイルを処理する必要がありますが、パフォーマンスが良いものを探しています。試してみましたが、diff -U 0
仕事に適したツールではないようです。
答え1
アークはどうですか?
$ awk -F, 'NR==FNR{a[$1,$2]=$3; next} ($1,$2) in a && $3 != a[$1,$2]' file1 file2
c,3,val3x
e,5,val5x
高度なCSV機能(特に簡単な方法では処理できない引用符付きCSVフィールドに含まれるコンマ)を処理する必要がある場合は、awk -F,
常にPythonベースのcsvkitツールバーがあります。特に、次のものを使用できますcsvsql
。
$ csvsql -H --query '
SELECT file2.* FROM file1 INNER JOIN file2 ON file1.a = file2.a AND file1.b = file2.b
WHERE file1.c != file2.c
' file1 file2 2>/dev/null
a,b,c
c,3,val3x
e,5,val5x
答え2
sed-grepパイプラインを使用して、次のことができます。
$ sed -e 's/$/x/' file1 | grep -xFf - file2
c,3,val3x
e,5,val5x
メモ:-
- まず、file2のデータに基づいて検索するfile1データを準備します。
-x
=>一部ではなく行全体を一致させます。-F
=>正規表現一致ではなく文字列一致の場合-f
=>ファイルに探している文字列が含まれています。