2012-10-05 3 views
0

텍스트 파일에서 여러 문자열 검색 :효율적인 나는 매우 긴 파일 (라인 100 만) 여러 문자열의 정확한 일치를 찾기 위해 <strong>egrep을</strong>를 사용

egrep "\<string1\>|<\string2\>" my_file 

하지만 너무 많은 시간이 걸립니다 심지어 두 개의 문자열 만 찾습니다. 어커런스가 발견 되더라도 파일의 전체 라인을 따라 모든 문자열을 찾습니다. 실제로 파일에 각 문자열이 한 번만 나타나는 것을 알고 있습니다. 그러면 egrep이 문자열을 찾은 다음 강제로 찾고 문자열의 다음 항목을 찾도록 문자열을 찾는 것을 멈추게하려고합니다. 아니면 그렇게 효율적으로 할 수있는 또 다른 방법이 있다면.

감사합니다.

+0

몇 개의 문자열을 찾고 싶습니까? 몇 천이나되는 것과 같은 것이 있습니까? –

답변

2

일치의 수를 제한 -m 옵션이있다. 할 수있는 일은 서브 패턴을 반복하는 것입니다. fgrep -m 1 :

for pat in $patterns; do 
    fgrep -m 1 $pat my_file 
done 

P.S. 또 다른 옵션은 복잡한 패턴을 사용하고 하위 패턴 수와 동일한 개수의 일치를 지정하는 것입니다.하지만 각 파일 행의 비교 속도가 느려집니다.

+0

답변 해 주셔서 감사합니다. -max-count = NUM ​​ – saloua

+0

단점 : OP는 모든 문자열이 파일 당 최대 한 번 발생한다는 것을 감안할 때'--max-count = 1 '의 평균 속도 향상은 겨우 200 %입니다. –

+0

복잡한 패턴 w/일치가 실제로는 가장 빠른 하위 패턴 수와 같다고 생각합니다. 설명에 대한 내 대답을 참조하십시오. –

1

잘 모르겠어요,하지만 어쩌면이 하나 더 빠르다 :

grep -e '<pattern1>' -e '<pattern2>' -e '<pattern3>' your_file 

-F

또한 일의 속도가 빨라질 수 있습니다, 당신의 패턴이 정말 패턴하지 생각합니다. 또한, 출력 결과가 grep이라면 선택의 여지가 없지만 모든 패턴을 찾아야한다고 생각합니다. 다음은 모든 서브 패턴 1 선을 얻을 것이기 때문에

-m NUM, --max-count=NUM 
    Stop reading a file after NUM matching lines. 

당신은 비록 복잡한 패턴으로 직접 사용할 수 없습니다 :

+0

나는 단어 패턴을 문자열로 바꾼 것이 더 좋다 : 검색된 문자열을 포함하는 배열을 반복적으로 던지지 않기 때문에 egrep을 사용해야한다.그런 다음 매개 변수 확장을 사용하여 작성합니다. 그리고 마지막으로 egrep을 사용하여 이들을 찾습니다. – saloua

+0

'egrep'이 필요한 이유는 아직도 잘 모르겠습니다. 'grep -F -e 'string1'-e 'string2'-e 'string3'your_file'보다 더 좋은 방법입니다. 해봤습니까? –

+0

예, Lev가 말했듯이이 명령 줄에'-m 2 '를 추가해도 개선 될 것입니다. 처음에는 줄 당 하나의 패턴뿐만 아니라 각 패턴에 일치하는 줄이 하나만 있다는 것을 알지 못했습니다. –

2

검색 최적화 방법은 grep 구현에서 사용하는 알고리즘에 따라 다릅니다. egrep에 대한 "전통적인"알고리즘은 패턴을 결정적 유한 오토 마톤으로 컴파일하는 것입니다. 그것이 무엇인지 모르는 것이라면 걱정하지 마십시오. 중요한 것은 컴파일 작업이 조금 걸립니다.하지만 일단 완료되면 속도가 빠르며 속도가 원하는 패턴의 복잡성에 의존하지 않습니다. 에 대한. 실제로 컴파일이 완료되면 egrep은 fgrep보다 실제로 빠릅니다. 즉, fgrep은 작은 파일에서 가장 빠르며 egrep은 대용량 파일에서 가장 빠릅니다.

적어도 이것이 [ef] grep의 전통적인 구현 상황입니다. 가장 현대적인 구현은 적응력이 있으며 상황에 따라 알고리즘을 전환한다고 생각합니다 (예 : 현대 fgreps는 충분히 큰 파일을 위해 컴파일 된 DFA 모드로 전환합니다). 구현을 위해 가장 빠른 것을 찾으려면 시간이 많이 소요되는 실험을 해봐야합니다.

다음과 같이 몇 가지 권장 사항을 제공 할 수 있습니다. 첫째, 파일을 여러 번 스캔해야하므로 검색을 두 번 이상 (예 : 각 단어에 대해 fgrep 실행)하지 마십시오. 둘째, 문자열의 수를 최소화하는 것에 대해 걱정할 필요가 없습니다. 어쨌든 중요하지 않은 최상의 모드에 있기 때문입니다. 셋째, @ Lev의 제안 인 -m을 사용하여 필요한 부분을 찾은 후에 중지하십시오 (비록 두 단어 모두 -m2으로 단일 검색이 될 것이라고 확신하지만).

+0

아주 좋은 답변입니다, 감사합니다. 마침내 내가 DFA를 보게 만들었지 :) –