A
두 개의 정렬된 파일 이 있는데 B
크기가 A
훨씬 큽니다 B
. 예를 들어 A는 100GB이고 B는 50MB입니다. 나는 원해요빠르게의 행이 B
에 포함되어 있는지 확인하고 A
일치하는 항목이 있으면 중지합니다. 현재 이 목적을 위한 Python 스크립트가 있지만 다른 프로세스에 대해 프로세스를 수천 번 반복해야 하면 느리게 실행됩니다 B
.
답변1
를 사용하면 및 fifo를 사용하여 comm
첫 번째 일치에서 스크립트가 반환되도록 할 수 있습니다.head
#!/bin/bash -e
[ -p tmpfifo ] || mkfifo tmpfifo
comm -12 A B | head -n1 >tmpfifo &
# If this wc is zero, no matches. Otherwise, a match was found.
# You can use this directly in the script, echo it,
# change the script exit value, or however else you need to use it.
wc -l tmpfifo
현재 이것은 백그라운드에서 계속 통신을 수행하고 있으며 PID
죽일 권리( 살인이 아닌 $!
주는 것 )를 찾는 데 어려움을 겪고 있습니다. 이것이 실행 중인 유일한 통신이라고 확신하는 경우에는 작동 하지만 다른 통신이 실행 중이면 위험할 수 있습니다. head
comm
killall
답변2
AWK를 사용하여 파일을 구문 분석해 볼 수 있습니다. 처음에는 더 큰 파일을 분할하거나 A를 mem에 저장하고 B를 실행하여 각 행을 mem의 A와 비교하고 싶었습니다. 그러나 내 생각에는 AWK가 당신이 찾고 있는 것일 수도 있습니다.
http://www.linuxjournal.com/article/8913프라이머에요
http://forums.devshed.com/unix-help-35/compare-two-files-using-awk-or-sed-425150.html파일 비교에 대해 이야기합니다. 저는 지금 Linux를 사용하고 있지 않습니다. 아니면 테스트해 보겠습니다.
멍하니http://www.gnu.org/software/gawk/manual/html_node/index.html
답변3
파일이 정렬된 경우에는 Join(1) 또는 merge(1)를 사용하여 상당히 효율적으로 작업할 수 있습니다. head -1
출력은 첫 번째 줄에서 중지되고 종료 시 SIGPIPE를 사용하여 명령의 나머지 부분을 종료합니다.
또한 더 큰 파일 A에서 uniq(1)을 사용하면 문제 크기를 줄일 수 있습니다. 이는 다른 라인 세트로 요약되어 B 파일 목록과 비교할 수 있습니다.
또 다른 가능성은 다음을 수행하도록 Python 스크립트를 조정하는 것입니다.
For each B file:
Read in each line
Add the file name to a list of files keyed on a hash of the line
Loop through the A file:
Look up each line in the dictionary
Output the file name when a match is found.
"B" 파일의 다른 줄 수가 많으면 메모리를 많이 차지하므로 실용적일 수도 있고 그렇지 않을 수도 있습니다. 거짓 긍정을 제거하기 위한 사후 처리가 마음에 들지 않으면 이 단계에서 해시만 저장하여 메모리 소비를 줄일 수 있습니다.
세 번째 접근 방식은 모든 데이터를 데이터베이스에 로드하고 연결하는 것입니다. 그러나 이렇게 하면 데이터를 가져오는 오버헤드가 발생하여 너무 커질 수 있습니다. 적절한 인덱스를 사용하면 실제 일치 쿼리가 매우 빨라지고 모든 B 파일을 한 번에 확인할 수 있습니다.
Create table A (
TextLine varchar (100) -- or whatever length you need
)
Create table B (
TextLine varchar (100)
,Filename varchar (20)
)
Alter table B
add constraint PK_B
primary key (TextLine, FileName)
select distinct B.FileName
from A
join B
on a.TextLine = B.TextLine
답변4
grep -F -x -f B A | head -n 1
이것은 grep의 잘 알려진 기능은 아니지만 각 패턴을 한 줄에 배치하여 단일 파일을 통해 여러 패턴을 전달할 수 있습니다. 이는 -F
정확한 문자열을 찾기 위해 와 함께 사용할 때 가장 유용합니다 ( 를 사용할 경우 -E
효과는 로 구분된 여러 패턴과 동일합니다 |
).
아직 벤치마킹은 안해봤지만 A 전처리 없이 최대한 빨리 나왔으면 좋겠습니다.