Command-Line
將文件視為集合併對其執行集合操作的 Linux 工具
有誰知道專門設計用於將文件視為集合併對其執行集合操作的任何 linux 工具?像差異,交叉點等?
假設元素是除 NUL 和換行符以外的字元串(但請注意,換行符在文件名中有效),您可以將集合表示為每行一個元素的文本文件,並使用一些標準的 Unix 實用程序。
設置會員資格
$ grep -Fxc 'element' set # outputs 1 if element is in set # outputs >1 if set is a multi-set # outputs 0 if element is not in set $ grep -Fxq 'element' set # returns 0 (true) if element is in set # returns 1 (false) if element is not in set $ awk '$0 == "element" { s=1; exit }; END { exit !s }' set # returns 0 if element is in set, 1 otherwise. $ awk -v e='element' '$0 == e { s=1; exit } END { exit !s }'
設置交點
$ comm -12 <(sort set1) <(sort set2) # outputs intersect of set1 and set2 $ grep -xF -f set1 set2 $ sort set1 set2 | uniq -d $ join -t <(sort A) <(sort B) $ awk '!done { a[$0]; next }; $0 in a' set1 done=1 set2
設置平等
$ cmp -s <(sort set1) <(sort set2) # returns 0 if set1 is equal to set2 # returns 1 if set1 != set2 $ cmp -s <(sort -u set1) <(sort -u set2) # collapses multi-sets into sets and does the same as previous $ awk '{ if (!($0 in a)) c++; a[$0] }; END{ exit !(c==NR/2) }' set1 set2 # returns 0 if set1 == set2 # returns 1 if set1 != set2 $ awk '{ a[$0] }; END{ exit !(length(a)==NR/2) }' set1 set2 # same as previous, requires >= gnu awk 3.1.5
設置基數
$ wc -l < set # outputs number of elements in set $ awk 'END { print NR }' set $ sed '$=' set
子集測試
$ comm -23 <(sort -u subset) <(sort -u set) | grep -q '^' # returns true iff subset is not a subset of set (has elements not in set) $ awk '!done { a[$0]; next }; { if !($0 in a) exit 1 }' set done=1 subset # returns 0 if subset is a subset of set # returns 1 if subset is not a subset of set
設置聯合
$ cat set1 set2 # outputs union of set1 and set2 # assumes they are disjoint $ awk 1 set1 set2 # ditto $ cat set1 set2 ... setn # union over n sets $ sort -u set1 set2 # same, but doesn't assume they are disjoint $ sort set1 set2 | uniq $ awk '!a[$0]++' set1 set2 # ditto without sorting
設置補碼
$ comm -23 <(sort set1) <(sort set2) # outputs elements in set1 that are not in set2 $ grep -vxF -f set2 set1 # ditto $ sort set2 set2 set1 | uniq -u # ditto $ awk '!done { a[$0]; next }; !($0 in a)' set2 done=1 set1
設置對稱差
$ comm -3 <(sort set1) <(sort set2) | tr -d '\t' # assumes not tab in sets # outputs elements that are in set1 or in set2 but not both $ sort set1 set2 | uniq -u $ cat <(grep -vxF -f set1 set2) <(grep -vxF -f set2 set1) $ grep -vxF -f set1 set2; grep -vxF -f set2 set1 $ awk '!done { a[$0]; next }; $0 in a { delete a[$0]; next }; 1; END { for (b in a) print b }' set1 done=1 set2
電源組
一組顯示空間的所有可能子集分隔,每行一個:
$ p() { [ "$#" -eq 0 ] && echo || (shift; p "$@") | while read r; do printf '%s %s\n%s\n' "$1" "$r" "$r"; done; } $ p $(cat set)
(假設元素不包含 SPC、TAB(假設預設值為
$IFS
)、反斜杠、萬用字元)。設置笛卡爾積
$ while IFS= read -r a; do while IFS= read -r b; do echo "$a, $b"; done < set1; done < set2 $ awk '!done { a[$0]; next }; { for (i in a) print i, $0 }' set1 done=1 set2
不相交集測試
$ comm -12 <(sort set1) <(sort set2) # does not output anything if disjoint $ awk '++seen[$0] == 2 { exit 1 }' set1 set2 # returns 0 if disjoint # returns 1 if not
空集測試
$ wc -l < set # outputs 0 if the set is empty # outputs >0 if the set is not empty $ grep -q '^' set # returns true (0 exit status) unless set is empty $ awk '{ exit 1 }' set # returns true (0 exit status) if set is empty
最低限度
$ sort set | head -n 1 # outputs the minimum (lexically) element in the set $ awk 'NR == 1 { min = $0 }; $0 < min { min = $0 }; END { print min }' # ditto, but does numeric comparison when elements are numerical
最大
$ sort test | tail -n 1 # outputs the maximum element in the set $ sort -r test | head -n 1 $ awk '$0 > max { max = $0 }; END { print max }' # ditto, but does numeric comparison when elements are numerical
全部可在http://www.catonmat.net/blog/set-operations-in-unix-shell-simplified/