답변:
당신의 목표가 공통적이거나 흔하지 않은 선을 찾는 comm
것이라면 , 여기 내 명령이 될 것입니다.
두 파일을 비교하여 파일 1에 고유 한 행, 파일 2에 고유 한 행 및 두 파일에 각각 표시되는 행을 세 열로 표시합니다. 이 출력을 억제하기 위해 플래그를 전달할 수도 있습니다. 예를 들어 comm -1 file1 file2
file1에 고유 한 첫 번째 열은 표시하지 않습니다. comm -12 file1 file2
두 파일에만 표시됩니다.
한 가지 큰 경고가 있습니다. 입력을 정렬해야합니다. 이 문제를 해결할 수 있습니다.
이것은 mno가 아닌 abc의 모든 것을 보여줍니다 :
comm -23 <(sort abc.txt) <(sort mno.txt)
그리고 당신은 그것을 wc -l
계산하기 위해 그것을 파이프 수 있습니다.
내가 함께하는 이유 comm
는 파일이 정렬되면 나란히 비교가 계산적으로 간단하기 때문입니다. 수백만 가지를 다루는 경우 차이가 있습니다.
이것은 몇 가지 모의 파일로 설명 할 수 있습니다. 나는 접근 방식의 차이를 보여주기 위해 상당히 빠른 컴퓨터를 가지고 있습니다. 매우 거대한 샘플 세트가 필요합니다. 파일 당 10 백만 개의 10 문자 문자열로 이동했습니다.
$ cat /dev/urandom | tr -dc '0-9' | fold -w 10 | head -10000000 > abc.txt
$ cat /dev/urandom | tr -dc '0-9' | fold -w 10 | head -10000000 > mno.txt
$ time comm -23 <(sort abc.txt) <(sort mno.txt) | wc -l
... 0m10.653s
$ time grep -Fcxv -f abc.txt mno.txt
... 0m23.920s
$ time grep -Fcwv -f abc.txt mno.txt
... 0m40.313s
$ time awk 'NR==FNR{a[$0]++};NR!=FNR && a[$0]' abc.txt mno.txt | wc -l
... 0m12.161s
정렬은 대부분의 시간이 걸립니다. abc.txt가 정적 인 척하는 경우 미리 정렬하면 향후 비교가 훨씬 빨라집니다.
$ sort abc.txt abc-sorted.txt
$ time comm -23 abc-sorted.txt <(sort mno.txt) | wc -l
... 0m7.426s
이것들을보고 몇 초와 관련이없는 것을 고려할 수 있지만 고급 머신에서 실행되고 있음을 강조해야합니다. Raspberry Pi 3 (예 : Raspberry Pi 3)에서이 작업을 수행하려는 경우 처리 속도가 훨씬 느려지고 실제로 중요한 지점까지 차이가 커집니다.
목록을 얻으려면 :
grep -Fwf abc.txt mno.txt
그것은 당신에게 비슷한 것을 제공합니다 :
abcd
abcd
zef
고유 한 목록을 얻으려면 다음과 같이 사용하십시오.
grep -Fwf abc.txt mno.txt | sort | uniq
카운트를 얻으려면 :
grep -Fcwv -f abc.txt mno.txt
-F
의미 : 정규 표현식 대신 고정 문자열 목록으로 PATTERN을 해석하십시오.-f
FILE에서 패턴을 얻습니다 abc.txt
.mno.txt
는 패턴 을 찾는다-c
경기 수를 센다-w
"전체 단어"만 찾으십시오. 일치하는 부분 문자열은 줄의 시작 부분에 있거나 단어가 아닌 구성 문자가 앞에 와야합니다. 마찬가지로 행의 끝에 있거나 단어가 아닌 구성 문자가 와야합니다. 단어 구성 문자는 문자, 숫자 및 밑줄입니다.-v
검색 반전fgrep
, egrep
대체는 가정의 찬성 (사용되지 않습니다 grep -F
, grep -E
나는 누군가가 그들도 사라질 것이라고 믿고 확실하지 않다하더라도 -
-x
때 사용해야 -F
합니까?
abcdef
그 값이 일치하거나 일치하지 않아야 abcd
합니까?
awk를 사용하여 두 개의 파일, 먼저 패턴 파일을 확인한 다음 확인하려는 파일을 전달하여 작업을 수행 할 수 있습니다. 첫 번째 파일을 읽을 때, 우리는 그 NR==FNR
줄을 배열로 읽을 수 있다는 것을 알고 있습니다. 때 NR!=FNR
같은 라인의 배열이 설정되어있는 경우 우리는 확인한다.
$ cat abc.txt
abcd
xyz
pqrs
$ cat mno.txt
zzon
xyz
mkno
abcd
$ awk 'NR==FNR{a[$0]++};NR!=FNR && a[$0]' abc.txt mno.txt
xyz
abcd
반대로, 패턴을 무효화하여 해당 라인에없는 라인을 인쇄 할 수 있습니다 abc.txt
$ awk 'NR==FNR{a[$0]++};NR!=FNR && ! a[$0]' abc.txt mno.txt
zzon
mkno
그리고 우리는 우리가 채택 할 수있는 사람들의 수를 인쇄 할 경우 sort
및 wc
:
$ awk 'NR==FNR{a[$0]++};NR!=FNR && ! a[$0]' abc.txt mno.txt | sort -u | wc -l
2
abc.txt
- mno.txt
입니다 {xyz, pqrs}
.
단어 목록 중 하나가 정렬되지 않은 경우 효율적인 집합 데이터 구조를 사용하여 공통 단어를 기억하는 것이 더 빠릅니다.
#!/usr/bin/env python3
import sys
with open(sys.argv[1]) as minuend_file:
minuend = frozenset(map(str.rstrip, minuend_file))
with open(sys.argv[2]) as subtrahend_file:
subtrahend = frozenset(map(str.rstrip, subtrahend_file))
difference = minuend - subtrahend
#print(*difference, sep='\n') # This prints the content of the set difference
print(len(difference)) # This prints the magnitude of the set difference
용법:
python3 set-difference.py abc.txt mno.txt
중간 저장 및 런타임을 위해 약간의 메모리를 저장하려면 약간 이해하기 어려운 프로그램을 사용할 수 있습니다.
#!/usr/bin/env python3
import sys
with open(sys.argv[1]) as minuend_file:
minuend = set(map(str.rstrip, minuend_file))
with open(sys.argv[2]) as subtrahend_file:
subtrahend = map(str.rstrip, subtrahend_file)
minuend.difference_update(subtrahend)
difference = minuend
del minuend
#print(*difference, sep='\n') # This prints the content of the set difference
print(len(difference)) # This prints the magnitude of the set difference
주어 abc.txt
와 mno.txt
10 임의 ASCII 숫자 문자의 1 개 미오 분류되지 않은 라인 각 (셋업에 대한 OLI의 답변을 참조)
$ time python3 set-difference.py abc.txt mno.txt
user 0m10.453s
vs.
$ export LC_COLLATE=C
$ time sort abc.txt > abc_sorted.txt
user 0m10.652s
$ time sort mno.txt > mno_sorted.txt
user 0m10.767s
$ time comm -23 abc_sorted.txt mno_sorted.txt | wc -l
9989882
user 0m1.600s
총 23 초
grep -cxvFf abc.txt mno.txt
?