파일을 컬렉션으로 처리하고 컬렉션 작업을 수행하도록 특별히 설계된 Linux 도구를 아는 사람이 있습니까? 차이점, 교차점 등?
답변1
요소가 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 '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