grep 정규식 솔루션(탐욕은 작동하지 않음)

grep 정규식 솔루션(탐욕은 작동하지 않음)

내 data.txt 파일에 다음 텍스트가 있습니다.

:MENU1
0. public
1. admin
2. webmail

:SYNTAX
! opt1, ... :

:ERROR1
Error #1, blah... blah.. blah...
Please do ...

:ERROR2
Error #2 ...

:MENU1정규식(PERL 구문)을 사용하여 다음 첫 번째 부분 을 추출하고 결과에서 마지막 부분을 :제거하고 싶습니다 .MENU1:

여러 정규 표현식을 시도했지만 가장 가까운 솔루션에서는 "탐욕스러운" 옵션을 사용할 수도 없고 마지막 ":"도 버릴 수 없었습니다.

grep -Poz "^:MENU1\K[\w\W]*:"

이것은 grep과 함께 작동
하지만 모든 텍스트를 마지막 ":"까지 가져옵니다...
다음 ":" 이후까지 원합니다 :MENU1.

0. public
1. admin
2. webmail
 

(끝 부분의 빈 줄에 주목하세요)

답변1

이 패턴은 *:마지막 패턴까지 모든 것과 일치합니다 :. 다음에 있어야 :할 곳에서 멈춰라 *?:. 예를 들어:

% grep -Poz '^:MENU1\K[\w\W]*?:' data.txt 

0. public
1. admin
2. webmail

:

앞에 개행 문자를 일치시켜 첫 번째 줄을 제거할 수 있습니다 \K. 예를 들어:

% grep -Poz '^:MENU1\n\K[\w\W]*?:' data.txt 
0. public
1. admin
2. webmail

:

빈 줄을 먹으려면 :텍스트를 일치시키고 버릴 수 있습니다. 예를 들어:

% grep -Poz '^:MENU1\n\K[\w\W]*?(?=\n+:)' data.txt 
0. public
1. admin
2. webmail

다음으로 다음을 제외한 모든 항목과 일치하도록 문자 클래스를 단순화할 수 있습니다 :.

% grep -Poz '^:MENU1\n\K[^:]*?(?=\n+:)' data.txt 
0. public
1. admin
2. webmail

마지막으로 일치의 초기 부분을 다시 작성할 수 있습니다.

% grep -Poz '(?<=:MENU1\n)[^:]*?(?=\n+:)' data.txt 
0. public
1. admin
2. webmail

이는 @terdon의 아이디어와 유사하지만 grep을 다시 호출하지 않고 빈 줄을 처리합니다.

궁극적인 정규식 익스플로잇주위를 둘러보세요역설. 이는 일치는 가능 하지만 출력에는 포함되지 않도록 하는 어설션 (?<=pattern)입니다 . 이는 출력에 포함하지 않고 후행 패턴을 일치시킬 수 있는 어설션 입니다 .look-behindpattern(?=pattern)look-ahead

답변2

무엇에 대해서: grep -Poz "^:MENU1\K[^:]*"?

답변3

@Herbert의 솔루션은 아마도 가장 간단하지만 둘러보기를 사용할 수도 있습니다.

$ grep -Poz '(?<=:MENU1\n)[^:]*' file 
0. public
1. admin
2. webmail
  

관련 정보