列の値が変更された行のみを取得するには、比較してください。

列の値が変更された行のみを取得するには、比較してください。

次の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=>ファイルに探している文字列が含まれています。

関連情報