比较两个文件并根据第一列和第二列从第二个文件中获取不匹配的行

比较两个文件并根据第一列和第二列从第二个文件中获取不匹配的行

我有两个管道分隔文件,如下所示

文件1

TEST|123456
TEST|123457
TEST|123458
TEST|123459
TEST|123460

文件2

TEST|123456|RAY|DOE||
TEST|123457|JANE|DOE||
TEST|123458|ROSE|DAWN||
TEST|123459|GEORGE|BRID||
TEST|123460|RALPH|DOE||
TEST|123461|JOHN|DOE||
TEST|123462|STEVE|SMITH||

文件 3 - 所需输出

TEST|123461|JOHN|DOE||
TEST|123462|STEVE|SMITH||

我想使用 file1 和 file2 的第一列和第二列作为从文件 2 中获取不匹配行的关键。

答案1

joinGNU coreutils 有一个-v选项,可以从两个源文件之一打印不可配对的行。使用它来反转匹配效果很好:

$ cat file1.txt
TEST|123456
TEST|123457
TEST|123458
TEST|123459
TEST|123460

$ cat file2.txt
TEST|123456|RAY|DOE||
TEST|123457|JANE|DOE||
TEST|123458|ROSE|DAWN||
TEST|123459|GEORGE|BRID||
TEST|123460|RALPH|DOE||
TEST|123461|JOHN|DOE||
TEST|123462|STEVE|SMITH||

$ join -t '|' -j 2 -o '2.1,2.2,2.3,2.4' -v 2 file1.txt file2.txt
TEST|123461|JOHN|DOE
TEST|123462|STEVE|SMITH

答案2

尝试:

$ awk -F'|' 'FNR==NR{a[$1,$2]=1; next}  !a[$1,$2]' file1 file2
TEST|123461|JOHN|DOE||
TEST|123462|STEVE|SMITH||

怎么运行的

  • -F'|'告诉 awk 用作|字段分隔符。

  • FNR==NR{a[$1,$2]=1; next}

    对于属于第一个文件 ( FNR==NR) 的行,这告诉 awk 将一个条目添加到a键 为$1,$2且值为 的关联数组中1

  • !a[$1,$2]

    这告诉 awk 打印任何为!a[$1,$2]true 的行。由于!是逻辑否定,这意味着打印任何为a[$1,$2]假(零)的行。

    这意味着我们设置的行将a[$1,$2]=1被跳过(不打印)。其他行将被打印。

答案3

Grep 可以选择从文件中获取要匹配的正则表达式。
要使第一个文件成为正则表达式,我们只需^在每行的开头添加 a 。这可以通过 sed 命令来完成,例如sed 's/.*/^&/' file1.

然后我们将 sed 的输出提供给 grep,如下所示(ksh、zsh、bash):

grep -vf <(sed 's/.*/^&/' file1) file2

答案4

软件工具方法:

sort -r file[12] | uniq -u -w11 | tac

相关内容