鉴于这两个文件:
$ cat A.txt $ cat B.txt
3 11
5 1
1 12
2 3
4 2
我想在B中找到A“但不是”中的行号。它的unix命令是什么?
我试过这个,但似乎失败了:
comm -3 <(sort -n A.txt) <(sort -n B.txt) | sed 's/\t//g'
鉴于这两个文件:
$ cat A.txt $ cat B.txt
3 11
5 1
1 12
2 3
4 2
我想在B中找到A“但不是”中的行号。它的unix命令是什么?
我试过这个,但似乎失败了:
comm -3 <(sort -n A.txt) <(sort -n B.txt) | sed 's/\t//g'
comm -2 -3 <(sort A.txt) <(sort B.txt)
如果我理解正确的话,应该做你想做的事。
编辑:实际上,comm
需要按字典顺序对文件进行排序,因此您不需要-n
在sort
命令中:
$ cat A.txt
1
4
112
$ cat B.txt
1
112
# Bad:
$ comm -2 -3 <(sort -n B.txt) <(sort -n B.txt)
4
comm: file 1 is not in sorted order
112
# OK:
$ comm -2 -3 <(sort A.txt) <(sort B.txt)
4
你可以试试这个
$ awk 'FNR==NR{a[$0];next} (!($0 in a))' B.txt A.txt
5
4
请注意,awk 解决方案有效,但在 A 中保留了重复项(不在 B 中);python解决方案对结果进行重复数据删除
另请注意,comm
它不会计算真正的集差;如果一行在 A 中重复,而在 B 中重复的次数较少,comm
则会在结果中留下“额外”行:
$ cat A.txt
120
121
122
122
$ cat B.txt
121
122
121
$ comm -23 <(sort A.txt) <(sort B.txt)
120
122
如果不希望出现这种行为,请使用sort -u
删除重复项(仅 A 中的重复项):
$ comm -23 <(sort -u A.txt) <(sort B.txt)
120
我最近编写了一个名为 Setdown 的程序,它从 cli 执行 Set 操作。
它可以通过编写类似于您在 Makefile 中编写的定义来执行集合操作:
someUnion: "file-1.txt" \/ "file-2.txt"
someIntersection: "file-1.txt" /\ "file-2.txt"
someDifference: someUnion - someIntersection
它很酷,你应该检查一下。我个人不建议使用不是为作业构建的临时命令来执行集合操作。当您确实需要执行许多集合操作或者您有任何相互依赖的集合操作时,它不会很好地工作。不仅如此,setdown 还允许您编写依赖于其他集合操作的集合操作!
无论如何,我认为这很酷,您应该完全检查一下。
注意:我认为 Setdown 比 comm 好得多,因为Setdown 不需要您正确排序输入。相反,Setdown 会为您对输入进行排序,并使用外部排序。因此它可以处理大量文件。我认为这是一个主要的好处,因为我忘记对传递给 comm 的文件进行排序的次数已经数不胜数了。
这是另一种方法join
:
join -v1 <(sort A.txt) <(sort B.txt)
从文档中join
:
'-v file-number' 为文件 file-number('1' 或 '2')中每个不可配对的行打印一行,而不是正常输出。