Bash 集减法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11963844/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Bash set subtraction
提问by Robottinosino
How to subtract a set from another in Bash?
如何在 Bash 中从另一个集合中减去一个集合?
This is similar to: Is there a "set" data structure in bash?but different as it asks how to perform the subtraction, with code
这类似于:bash 中是否有“集合”数据结构?但不同,因为它询问如何使用代码执行减法
- set1: N lines as output by a filter
- set2: M lines as output by a filter
- set1: N 行作为过滤器的输出
- set2:M 行作为过滤器的输出
how to get:
怎么获得:
- set3: with all lines in N which don't appear in M
- set3:包含 N 中未出现在 M 中的所有行
回答by Nahuel Fouilleul
comm -23 <(command_which_generate_N|sort) <(command_which_generate_M|sort)
comm without option display 3 columns of output: 1: only in first file, 2: only in second file, 3: in both files. -23 removes the second and third columns.
不带选项的 comm 显示 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
Input files must be sorted.
输入文件必须排序。
GNU sort and comm depends on locale, for example output order may be different (but content must be the same)
GNU sort 和 comm 取决于语言环境,例如输出顺序可能不同(但内容必须相同)
(export LC_ALL=C; comm -23 <(command_which_generate_N|sort) <(command_which_generate_M|sort))
回答by YSC
uniq -u(manpage)is often the simplest tool for list subtraction:
uniq -u(manpage)通常是最简单的列表减法工具:
Usage
用法
uniq [OPTION]... [INPUT [OUTPUT]]
[...]
-u, --unique
only print unique lines
Example: list files found in directory a but not in b
示例:列出在目录 a 中找到但不在 b 中的文件
$ ls a
file1 file2 file3
$ ls b
file1 file3
$ echo "$(ls a ; ls b)" | sort | uniq -u
file2
回答by Robert Massaioli
I wrote a program recently called Setdownthat does Set operations (like set difference) from the cli.
我最近编写了一个名为 Setdown 的程序,它从 cli 中执行设置操作(如设置差异)。
It can perform set operations by writing a definition similar to what you would write in a Makefile:
它可以通过编写类似于您在 Makefile 中编写的定义来执行设置操作:
someUnion: "file-1.txt" \/ "file-2.txt"
someIntersection: "file-1.txt" /\ "file-2.txt"
someDifference: someUnion - someIntersection
Its pretty cool and you should check it out. I personally don't recommend the "set operations in unix shell" post. It won't work well when you really need to do many set operations or if you have any set operations that depend on each other.
它很酷,你应该检查一下。我个人不推荐“在 unix shell 中设置操作”的帖子。当您确实需要执行许多集合操作或者您有任何相互依赖的集合操作时,它不会很好地工作。
At any rate, I think that it's pretty cool and you should totally check it out.
无论如何,我认为它很酷,你应该彻底检查一下。
回答by Christian Bongiorno
I've got a dead-simple 1-liner:
我有一个非常简单的 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 }'
baz
foo
By definition, 2 sets intersect if they have elements in common. In this case, there are 2 sets, so any count of 2 is an intersection - simply "subtract" them with grep
根据定义,如果两个集合具有共同的元素,则它们相交。在这种情况下,有 2 个集合,因此任何 2 的计数都是一个交集 - 只需用 grep“减去”它们

