
ファイルをコレクションとして処理し、コレクション操作を実行するように特別に設計されたLinuxツールを知っている人はいますか?違い、交差点など?
答え1
要素がNULと改行以外の文字列であると仮定すると(ファイル名では改行が有効であることに注意してください)、次のように表現できます。置く1行に1要素ずつテキストファイルとして保存され、いくつかの標準の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
パワーパック
1行に1つずつ、スペースで区切られたすべての可能なサブセットが表示されます。
$ 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 'NR == 1 || $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/
答え2
一種の。ソートは直接処理する必要がありますが、各行を集合メンバー(クロス、違い)comm
として処理することでこれを行うことができます。 (そして反転の違いを提供します。つまり、代わりに。)同盟はこの設定にあります。-12
-13
-23
set2 - set1
set1 - set2
sort -u
答え3
16.10以降、ミニコンソールツール「setop」はDebian StretchとUbuntuで利用可能になりました。あなたはそれを得ることができます
sudo apt install setop
ここにいくつかの例があります。作業するコレクションは別の入力ファイルとして提供されます。
setop input # is equal to "sort input --unique" setop file1 file2 --union # option --union is default and can be omitted setop file1 file2 file3 --intersection # more than two inputs are allowed setop file1 - --symmetric-difference # ndash stands for standard input setop file1 -d file2 # all elements contained in 1 but not 2
ブールクエリはEXIT_SUCCESS
trueの場合にのみ返され、EXIT_FAILURE
それ以外の場合はメッセージが返されます。このように、 setop はシェルで使用できます。
setop inputfile --contains "value" # is element value contained in input? setop A.txt B.txt --equal C.txt # union of A and B equal to C? setop bigfile --subset smallfile # analogous --superset setop -i file1 file2 --is-empty # intersection of 1 and 2 empty (disjoint)?
実際には、正規表現を介して入力ストリームを解析する方法を正確に説明することも可能です。
setop input.txt --input-separator "[[:space:]-]"
スペース(スペースなど\v
\t
\n
\r
\f
)またはマイナス記号が要素間の区切り文字として解釈されることを示します(デフォルトは改行です。つまり、入力ファイルの各行は要素です)。setop input.txt --input-element "[A-Za-z]+"
要素は単にラテン文字で構成される単語であり、他のすべての文字は要素間の区切り文字として扱われることを示します。
また、次のことができます。
--count
出力セットのすべての要素、--trim
すべての入力要素(スペース、カンマなどの不要な先行文字と末尾文字の両方を削除)- 空の要素を有効なビアとして扱います
--include-empty
。 --ignore-case
、--output-separator
要素間の出力ストリームを設定します(デフォルト\n
)。- など。
を参照してman setop
ください。github.com/phisigma/setopより多くの情報を知りたいです。
答え4
ファイルを一連の行として処理してファイルを並べ替えると、次のようになります。comm
。
ファイルを(複数の)行セットとして処理し、行がソートされていない場合は、差と交差を実行grep
できます(差と交差セットを実装しますが、複数セットの数は考慮しません)。アライアンスだけcat
。
grep -xF -f small large >intersection
grep -vxF -f small large >difference
cat small large >union