한 파일에서 다른 파일에없는 ID 찾기


9

두 개의 파일이 있습니다.

abc.txt

abcd
xyz
pqrs

mno.txt

zzon
mkno
abcd
  • mno.txt 파일에 "abcd"가 있는지 확인하고 싶습니다 .
  • "abcd"가 abc.txt 에서 처음 인 경우에는 mno.txt 에서도 처음 일 필요는 없습니다 .
  • 두 파일 모두에 수천 개의 ID가 있습니다.
  • 나는 또한에없는 얼마나 많은 아이디의 확인하려면 mno.txtabc.txt .

어떻게해야합니까?

답변:


19

당신의 목표가 공통적이거나 흔하지 않은 선을 찾는 comm것이라면 , 여기 내 명령이 될 것입니다.

두 파일을 비교하여 파일 1에 고유 한 행, 파일 2에 고유 한 행 및 두 파일에 각각 표시되는 행을 세 열로 표시합니다. 이 출력을 억제하기 위해 플래그를 전달할 수도 있습니다. 예를 들어 comm -1 file1 file2file1에 고유 한 첫 번째 열은 표시하지 않습니다. 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)에서이 작업을 수행하려는 경우 처리 속도가 훨씬 느려지고 실제로 중요한 지점까지 차이가 ​​커집니다.


7

목록을 얻으려면 :

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을 해석하십시오.
  • -fFILE에서 패턴을 얻습니다 abc.txt.
  • 우리 mno.txt는 패턴 을 찾는다
  • -c 경기 수를 센다
  • -w"전체 단어"만 찾으십시오. 일치하는 부분 문자열은 줄의 시작 부분에 있거나 단어가 아닌 구성 문자가 앞에 와야합니다. 마찬가지로 행의 끝에 있거나 단어가 아닌 구성 문자가 와야합니다. 단어 구성 문자는 문자, 숫자 및 밑줄입니다.
  • -v 검색 반전

1
영업 이익이 원한다면 계수 일치, 더처럼 안된다고 grep -cxvFf abc.txt mno.txt?
스틸 드라이버

방금 봤어 : D ... 너는 항상 나를 구하기 위해 여기에 : D
Ravexina

참고로 fgrep, egrep대체는 가정의 찬성 (사용되지 않습니다 grep -F, grep -E나는 누군가가 그들도 사라질 것이라고 믿고 확실하지 않다하더라도 -
steeldriver

사용할 -x때 사용해야 -F합니까?
Ravexina 2016 년

1
그것은 OP가 정확히 계산하고자하는 것에 달려 있습니다-예를 들어 mno.txt에 abcdef그 값이 일치하거나 일치하지 않아야 abcd합니까?
스틸 드라이버

3

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

그리고 우리는 우리가 채택 할 수있는 사람들의 수를 인쇄 할 경우 sortwc:

$ awk 'NR==FNR{a[$0]++};NR!=FNR && ! a[$0]' abc.txt  mno.txt | sort -u | wc -l         
2

나는 당신이 주변에 잘못된 길을 가지고 있다고 생각합니다. 지금까지 내가 질문을 이해, 영업 이익의 설정 차이 (크기)를 계산하고 싶어 abc.txt- mno.txt입니다 {xyz, pqrs}.
David Foerster 2016 년

2

단어 목록 중 하나가 정렬되지 않은 경우 효율적인 집합 데이터 구조를 사용하여 공통 단어를 기억하는 것이 더 빠릅니다.

파이썬

#!/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.txtmno.txt10 임의 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 초

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.