csvファイルの2つの列を比較し、一致しないレコードのみを表示する

csvファイルの2つの列を比較し、一致しないレコードのみを表示する

次の形式のcsvファイルがあります。

1311,0008,a131,a131,7039
1311,0008,a131,a132,7039
1711,2046,a626565,a626566,7099
1711,2048,a626565,a626565,7035

私が望むのは、列3と4のみを比較し、一致しない場合は新しいファイルにその行を印刷し、一致する場合はその行を別のファイルに印刷することです。

予想されるFile1出力(列3と4が一致しません):

1311,0008,a131,a132,7039
1711,2046,a626565,a626566,7099

File2の予想出力(列3と4が一致):

1311,0008,a131,a131,7039
1711,2048,a626565,a626565,7035

これまでは複数のファイルを比較してみました。

答え1

awk -F, '{ print >($3==$4?"matchedFile":"notMatchedFile") }' infile

列#3が同じ場合は、オプションで2つの出力ファイルのいずれかに行をリダイレクトします。完全な文字列一致列#4(カンマで区切られた列、で指定されている-F,)を使用して、以下を作成します。matchedFile出力ファイル、それ以外の場合は書き込みnotMatchedFile

バラよりその他のマッチングオプションはこちら


$ head matchedFile notMatchedFile
==> matchedFile <==
1311,0008,a131,a131,7039
1711,2048,a626565,a626565,7035

==> notMatchedFile <==
1311,0008,a131,a132,7039
1711,2046,a626565,a626566,7099

または似ていますが、コマンドをより簡潔にします。

awk -F, '{ print >"file"($3==$4) }' infile

$ head file[01]
==> file0 <==
1311,0008,a131,a132,7039
1711,2046,a626565,a626566,7099

==> file1 <==
1311,0008,a131,a131,7039
1711,2048,a626565,a626565,7035

答え2

簡単に保つための2つの非常に短いコマンド:

awk -F, '$3 != $4' file.csv >file1
awk -F, '$3 == $4' file.csv >file2

両方のコマンドは、inの行をカンマ区切りのfile.csvフィールドセットとして扱います。 3番目のフィールドが4番目のフィールドと等しくない場合はいつでも、最初のコマンドは現在の行を書き込みます(そして出力リダイレクトを介してfile1書き込みます)。 2番目のコマンドは同じことを行いますが、反対のロジックを使用します(そして出力は次のようになりますfile2)。

単一のコマンドを使用することは少し複雑ですが、ファイル記述子3と4を単純にリダイレクトするだけで、コマンドラインから出力ファイルの名前を指定できます。

$ awk -F, '{ fd = $3 == $4 ? 4 : 3;  print >("/dev/fd/" fd) }' file.csv 3>file1 4>file2
$ cat file1
1311,0008,a131,a132,7039
1711,2046,a626565,a626566,7099
$ cat file2
1311,0008,a131,a131,7039
1711,2048,a626565,a626565,7035

それとも同じですが、もっと混乱しています。

awk -F, '{ print >("/dev/fd/" 3 + ($3 == $4)) }' file.csv 3>file1 4>file2

答え3

GNU sedメソッド:

F="[^,]*,"
sed -En "
  /^($F){2}($F)\\2/w match.csv"'
  //!w nomatch.csv
' file.csv

結果は現在のディレクトリのmatch / nomatch .CSVファイルに保存されます。

関連情報