按行比较两个文件并从第一个文件中删除重复项

Ank*_*ain 4 unix bash grep

问题:

  1. 需要比较两个文件,
  2. 从第一个文件中删除重复项
  3. 然后将 file1 的行附加到 file2

举例说明

假设,这两个文件是 test1 和 test2。

$ cat test2
www.xyz.com/abc-2
www.xyz.com/abc-3
www.xyz.com/abc-4
www.xyz.com/abc-5
www.xyz.com/abc-6
Run Code Online (Sandbox Code Playgroud)

而 test1 是

$ cat test1
www.xyz.com/abc-1
www.xyz.com/abc-2
www.xyz.com/abc-3
www.xyz.com/abc-4
www.xyz.com/abc-5
Run Code Online (Sandbox Code Playgroud)

比较 test1 和 test2并从测试 1 中删除重复项

结果要求:

$ cat test1
www.xyz.com/abc-1
Run Code Online (Sandbox Code Playgroud)

然后将此 test1 数据添加到 test2

$ cat test2
www.xyz.com/abc-2
www.xyz.com/abc-3
www.xyz.com/abc-4
www.xyz.com/abc-5
www.xyz.com/abc-6
www.xyz.com/abc-1
Run Code Online (Sandbox Code Playgroud)

尝试的解决方案:

join -v1 -v2 <(sort test1) <(sort test2)
Run Code Online (Sandbox Code Playgroud)

这导致了这个(这是错误的输出)

$ join -v1 -v2 <(sort test1) <(sort test2)
www.xyz.com/abc-1
www.xyz.com/abc-6
Run Code Online (Sandbox Code Playgroud)

我尝试的另一个解决方案是:

fgrep -vf test1 test2
Run Code Online (Sandbox Code Playgroud)

结果什么也没有。

and*_*lrc 7

使用 awk:

% awk 'NR == FNR{ a[$0] = 1;next } !a[$0]' test2 test1
www.xyz.com/abc-1
Run Code Online (Sandbox Code Playgroud)

分解:

NR == FNR { # Run for test2 only
  a[$0] = 1 # Store whole line as key in associative array
  next      # Skip next block
}
!a[$0]      # Print line from test1 that are not in a
Run Code Online (Sandbox Code Playgroud)


Joh*_*024 6

从 test1 中删除行,因为它们在 test2 中:

$ grep -vxFf test2 test1
www.xyz.com/abc-1
Run Code Online (Sandbox Code Playgroud)

覆盖 test1:

grep -vxFf test2 test1 >test1.tmp && mv test1.tmp test1
Run Code Online (Sandbox Code Playgroud)

将新的 test1 附加到 test2 的末尾:

cat test1 >>test2
Run Code Online (Sandbox Code Playgroud)

grep 选项

grep 通常打印匹配的行。 -v告诉 grep 做相反的事情:它只打印不匹配的行

-x 告诉 grep 进行整行匹配。

-F 告诉 grep 我们使用的是固定字符串,而不是正则表达式。

-f test2 告诉 grep 从文件 test2 中读取这些固定字符串,每行一个。