如何从命令行中找到Set - Subset的两个文件?

时间:2012-05-18 19:56:09

标签: linux bash unix set zsh

我有两个带有排序行的文件。一个文件(B)是另一个文件(A)的子集。我想在A中找到不在B中的所有行。理想情况下,我想创建一个包含这些行的文件(C)。这在Unix中是否可行?我正在寻找一个单行命令来执行此操作而不是编写脚本。我查看了joindiff命令,但是我找不到执行此操作的命令选项。谢谢你的帮助。

5 个答案:

答案 0 :(得分:13)

这将抑制公共线:

comm -3 a b

答案 1 :(得分:5)

这个怎么样:

grep -v -f B A > C

答案 2 :(得分:3)

您也可以使用diff执行此操作。 Diff(不像@ johlo的grep答案)关心顺序,适用于非排序文件(不像@ johnshen64的comm答案):

$ cat a
a
b
c
d
e
$ cat b
a
b
f
d
e
$ diff -dbU0 a b
--- a   2012-05-18 16:02:30.603386016 -0400
+++ b   2012-05-18 16:02:45.547817122 -0400
@@ -3 +3 @@
-c
+f

因此,您可以使用管道来获取省略的行 - 考虑顺序:

$ diff -dbU0 a b | tail -n +4 | grep ^- | cut -c2-
c

答案 3 :(得分:1)

join命令将执行您所要求的操作:

join -v 1 fileA fileB > fileC

演示:

$ cat fileA
a
c
d
g
h
t
u
v
z
$ cat fileB
a
d
g
t
u
z
$ join -v 1 fileA fileB
c
h
v

这假定您在问题中声明的已排序文件。对于未分类的文件:

join -v 1 <(sort fileA) <(sort fileB)

答案 4 :(得分:0)

Awk解决方案

输入文件

<强>一个

aaa
bbb
ccc

<强> B'/强>

ccc
ddd
eel

<强>代码

awk ' NR==FNR { A[$0]=1; next; }
{ if ($0 in A) { A[$0]=0; } }
END { for (k in A) { if (A[k]==1) { print k; } } } ' a b > c

c (输出文件)

bbb
aaa