2013-12-19 4 views
3

많은 파일에서 문제가 발생할 때마다 식별해야하는 문제가 있습니다. 이 발생은 여러 줄의 패턴을 기반으로 결정됩니다.일치하는 특수 조건을 사용하여 여러 줄에 걸쳐 고정 패턴에서 그렙/정규 표현 일치

제 경우에는 선행 공백이 있고 하나 이상의 연속 공백 문자가 포함되어 있거나 알려진 작은 단어 집합 (예 : '또는', 'and'등)이있는 리터럴을 식별하려고합니다. . 리터럴은 작은 따옴표로 결정됩니다. 그러나 저는 단지 네 줄 앞에 "LITERAL"이라는 단어가 들어있는 리터럴에만 관심이 있습니다. 여기

파일의 내용에 대한 몇 가지 예입니다 : 내가 출력 '푸'의 파일 및 목록 항목을 식별 할 것이다 위의 예에서

EXEC LITERAL 
    LEVEL 
    NAME 
    LENGTH 
    VALUE (' Foo') 
END EXEC 

EXEC LITERAL 
    LEVEL 
    NAME 
    VALUE ('Foo Bar') 
END EXEC 

EXEC LITERAL 
    LEVEL 
    NAME 
    VALUE ('Bar Foo') 
END EXEC 

EXEC LITERAL 
    LEVEL 
    NAME 
    VALUE ('Foo') 
END EXEC 

EXEC LITERAL 
    LEVEL 
    NAME 
    LENGTH 
    VALUE ('or Bar') 
END EXEC 

EXEC DEFINITION 
    LEVEL 
    NAME 
    LENGTH 
    VALUE ('Bar') 
END EXEC 

, '푸 바'와 '나 바'. 'Bar Foo'는 따옴표 안에서 단어를 분리하는 데 사용되는 공백이 하나의 공백 인 경우 허용되므로 허용되지 않습니다.

여러 공백의 인스턴스를 식별하고 공백을 유도하며 작은 단어 (여러 파이프를 통해)를 포함하는 grep 문을 구성 할 수 있었지만 grege를 정규식으로 사용할 수 없습니다. grep에서 정규 표현식을 지원하기 위해 pcregrep을 사용하는 것에 관한 다른 기사에서 언급 한 것을 보았습니다. 그 일을 기쁘게 생각하지만, 나는 정규 표현식으로 잃어버린 다소 빠릅니다.

지금까지 나는 다음과 같은 명령에 도착했습니다

pcregrep -M 'LITERAL.*\n.*\n.*\n.*\n.*VALUE.* ' test.txt 

를 불행하게도 그것은 '푸 바'예를 선택하지 않는다 (때문에의 4 × \ n 나는 가정). 다음 하나는 '푸 바'를 받았지만 픽업 '또는 바'하지 않습니다 또한

pcregrep -M 'LITERAL.*\n.*\n.*\n.*\n.*VALUE.* ' test.txt 

내가 위의 패턴을 충족시키지 않는 경우는 문자 그대로 집어 것 세트 더 큰 데이터를 테스트 할 때 (예 : 위와는 다른 다른 단어의 일부 임). 위의 예제 패턴을 형성하지 않는 VALUE 또는 LITERAL의 인스턴스를 무시하고 주어진 패턴으로 일치를 제한하는 표현식이 정말로 필요합니다.

이 문제를 해결하는 방법에 대한 도움이 가장 환영받을 것입니다.

답변

0

당신은 1. 정규식에서 개행 문자의 수를 고정하는 대신 오탐 (false positive) 2를 피하기 위해 LITERAL 앞에 단어 경계 \b을 지정할 수 . 또는 \n

pcregrep -M '\bLITERAL(?:(?!VALUE).|\n)*?VALUE[[:blank:]]*\('"'(?=.*[[:blank:]].*).*?'\)" file.txt 
에 대한 비 욕심 일치 지정
+0

목 at가 거의 거기에있다. 그러나 그것은 'Foo'를 집어 들고있다. 첫 번째 작은 따옴표 뒤에 공백이있는 경우 또는 VALUE?와 같은 줄에 작은 따옴표 사이에 공백이있는 경우 수정할 수 있습니까? 이렇게하면 'Foo'를 무시하고 내가 달성하려고하는 것을 만날 수 있습니다. – Metalskin

+0

@ Metalskin, 수정 된 버전은 VALUE 뒤에 괄호 사이에 최소한 하나의 공백이 있는지 확인합니다. 당신이 필요로하는 것만 큼 구체적인 것은 아니지만 정규 표현식이 제어 할 수없는 것처럼 보일 수 있습니다. – iruvar

+0

매우 가깝습니다! 하나의 마지막 문제 (주어진 예제에없는 것처럼 내 잘못입니다), "Foo Bar"가 있으면 그걸 가져 왔습니다.작은 따옴표 사이에 하나의 공백이 생기는 곳을 제외해야하지만 따옴표 안에 선행 또는 후행 공백이 있어서는 안됩니다. 내 질문을 업데이트하여 명확해질 것입니다. 아, 네가 필요한 부분만큼 구체적이지 않다고 말한 곳을 보았다. 시간이 없다면 정규식을 사용하여 그것을 정리하려고 노력할 것입니다. – Metalskin

2
cat file.txt | awk '/LITERAL/ {print}' FS="\n" RS="" | grep -v "END" 

당신은 끝이 전체 목록을 가질 수

cat file.txt | awk '/LITERAL/ {print}' FS="\n" RS="" 
+0

파일에 내 질문에 값만 포함되어 있으면 작동하지만 다른 데이터는 파일에 있으면 작동하지 않습니다. 나는 다른 것들로 가득 찬 파일에서 나의 질문으로부터 패턴을 찾으려고 노력하고있다. 그게 분명하지 않다면 사과드립니다. – Metalskin