比较 csv 文件的两列并仅显示不匹配的记录

比较 csv 文件的两列并仅显示不匹配的记录

我有一个以下格式的 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

如果 column#3 相同,则有选择地将行重定向到两个输出文件之一全字符串匹配使用column#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

两个非常短的命令,只是为了简单起见:

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

这两个命令都将 in 中的行视为file.csv一组逗号分隔的字段。每当第三个字段不等于第四个字段时,第一个命令就会写入当前行(并且file1通过输出重定向写入)。第二个命令执行相同的操作,但逻辑相反(并且输出转到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 文件中。

相关内容