Bash集减法

时间:2012-08-15 03:44:03

标签: bash

如何在Bash中从另一个中减去一个集合?

这类似于:Is there a "set" data structure in bash?但不同,因为它询问如何执行减法,代码为

  • set1:N行作为过滤器的输出
  • set2:M行作为过滤器的输出

如何获得:

  • set3:N中的所有行都没有出现在M

5 个答案:

答案 0 :(得分:10)

comm -23 <(command_which_generate_N|sort) <(command_which_generate_M|sort)

comm without option显示3列输出:1:仅在第一个文件中,2:仅在第二个文件中,3:在两个文件中。 -23删除第二列和第三列。

$ cat > file1.list
A
B
C
$ cat > file2.list
A
C
D
$ comm file1.list file2.list 
        A
B
        C
    D
$ comm -12 file1.list file2.list # In both
A
C
$ comm -23 file1.list file2.list # Only in set 1
B
$ comm -13 file1.list file2.list # Only in set 2
D

必须对输入文件进行排序。

GNU sort和comm依赖于语言环境,例如输出顺序可能不同(但内容必须相同)

(export LC_ALL=C; comm -23 <(command_which_generate_N|sort) <(command_which_generate_M|sort))

答案 1 :(得分:2)

uniq -u (manpage)通常是列表减法的最简单工具:

<强>用法

uniq [OPTION]... [INPUT [OUTPUT]] 
[...]
-u, --unique
    only print unique lines

示例:在目录a中找到但不在b

中的列表文件
$ ls a
file1  file2  file3
$ ls b
file1  file3

$ echo "$(ls a ; ls b)" | sort | uniq -u
file2

答案 2 :(得分:1)

I wrote a program recently called Setdown确实从cli中设置操作(如设置差异)。

它可以通过编写类似于在Makefile中编写的定义来执行set操作:

someUnion: "file-1.txt" \/ "file-2.txt"
someIntersection: "file-1.txt" /\ "file-2.txt"
someDifference: someUnion - someIntersection

非常酷,你应该检查一下。我个人不推荐“在unix shell中设置操作”的帖子。当你真的需要做很多设置操作或者你有任何相互依赖的设置操作时,它将无法正常工作。

无论如何,我认为这很酷,你应该完全检查一下。

答案 3 :(得分:1)

我有一个非常简单的1-liner:

$ now=(ConfigQC DBScripts DRE DataUpload WFAdaptors.log)

$ later=(ConfigQC DBScripts DRE DataUpload WFAdaptors.log baz foo)

$ printf "%s\n" $now $later | sort | uniq -c | grep -vE '[ ]+2.*' | awk '{print $2}'
baz
foo

根据定义,如果两个集合具有相同的元素,则它们相交。在这种情况下,有2组,因此任何2的计数都是一个交集-只需用grep“减去”它们即可。

答案 4 :(得分:0)

您可以使用差异

# you should sort the output
ls > t1
cp t1 t2

我用 vi 从 t2 中删除了一些条目

$ cat t1
AEDWIP.writeMappings.sam
createTmpFile.sh*
find.out
grepMappingRate.sh*
salmonUnmapped.sh*
selectUnmappedReadsFromFastq.sh*

$ cat t2
AEDWIP.writeMappings.sam
createTmpFile.sh*
salmonUnmapped.sh*
selectUnmappedReadsFromFastq.sh*

diff 报告 t1 中不在 t2 中的行

diff t1 t2
$ diff t1 t2
3,4d2
< find.out
< grepMappingRate.sh*

拼装版

diff t1 t2 | grep "^<" | cut -d " " -f 2
find.out
grepMappingRate.sh*