여러 파일에서 여러 줄 grep을 수행하는 방법은 무엇입니까?

여러 파일에서 여러 줄 grep을 수행하는 방법은 무엇입니까?

여러 로그 파일의 모든 위치에서 이 패턴을 가져오려고 합니다(참고: 이러한 패턴의 크기(예: 어쩌고 저쩌고 하는 횟수)는 크게 다를 수 있습니다).

   Found an txt File
    Blah
    Blah
    10019874
    Blah
    Blah
    Processed File   

다음 명령줄을 사용하세요.

 pcregrep -M 'Found an.*(\n|.)*10019874.*(\n|.)*Processed' log_*.txt

내 정규식으로 확인해 보세요.여기에 정규 표현식

나는 -M 여러 줄 플래그와 함께 pcregrep을 사용합니다. "log_"로 시작하고 ".txt"로 끝나는 모든 로그 파일에 나타납니다. 이 명령을 실행하면 "세그먼테이션 오류"가 반환됩니다.

이 작업을 수행하는 더 쉽고 더 좋은 방법이 있습니까?

답변1

댓글에서 말했듯이 게시한 명령은 내 LMDE(pcregrep 버전 8.31 2012-07-06)에서 제대로 작동합니다. 그러나 정규식은 찾고 있는 문자열의 일부만 지정하므로 일반을 사용하여 이 작업을 수행할 수도 있습니다 grep.

grep -A 6 'Found an' log_*.txt | grep -C 3 10019874

-A 6전달된 문자열과 다음 6줄과 일치하는 줄을 인쇄하고 3 -C 3을 인쇄 합니다.철사. 최종 결과는 pcregrep사용한 방법과 정확히 동일합니다.


스키마의 행 수가 다를 수 있는 경우 이는 세그폴트를 설명할 수 있습니다. 아마도 일부 파일에서는 일치하는 부분이 너무 길어서 메모리 부족 오류가 발생하는 것 같습니다. 이 문제를 해결하는 한 가지 방법은 다음과 같은 스크립트를 작성하는 것입니다.

perl -ne '$c=1 if /Found an/; ## set $c to 1 if this line matches 'Found on'
          if($c){               ## If $c is defined and non-0
            push @F,$_;         ## Add the current line to the @F array
            $c++ if /10019874/; ## Increment $c if this line matches '10019874'
            if(/Processed/){    ## If this line matches 'Processed'
                print "@F" if $c>1; ## Print the contents of @F if $c is >1
                @F=""; $c=0;         ## Empty @F, set $c to 0.
            }
           }' log_*.txt 

단일 라이너와 동일:

perl -ne '$c=1 if /Found an/; if($c){push @F,$_; $c++ if /10019874/; if(/Processed/){print "@F" if $c>1; @F=""; $c=0;}}' log_*txt 

관련 정보