일치하는 괄호까지 grep

일치하는 괄호까지 grep

다음과 같은 파일이 있습니다.

pin(ABC) {  
              a b c d e f {  
              abc  
              }  
             }  
pin(XYZ) {  
              g h i j k  {  
                      j k {  
                        cg {  
                     }  
                    }  
                   }  
                  }  
abcd pqrs rstu  
mango banana tree  
pin(PQR) {  
               mango  
         }  

이제 다음과 같이 텍스트를 grep하고 싶습니다. -
ABC를 입력으로 사용하면 출력은 아래와 같이 "pin(ABC) {"에서 시작하여 일치하는 대괄호 "}"까지 내용이 포함된 ABC라는 파일이어야 합니다.

pin(ABC) {  
              a b c d e f {  
              abc  
              }  
             }  

PQR을 제공하면 출력은 다음 내용을 포함하는 PQR이라는 파일이어야 합니다.

pin(PQR) {  
               mango  
         }  

잠깐만요, pin() 내부의 단어에 대해
한 가지 방법은 "pin(ABC"에서 다음 이름 "pin"으로 텍스트를 grep하고 출력을 "ABC"라는 파일로 보내는 것입니다. ABC가 다음인 경우에만 작동하지만 PQR 및 XYZ 사례에서 실패했습니다.

답변1

$ pcregrep -Mo 'pin\(ABC\) (\{([^{}]++|(?1))*\})' file
pin(ABC) {
              a b c d e f {
              abc
              }
             }

pcregrepGNU는 없지만 PCRE grep모드를 지원하도록 빌드되었으며 파일이 너무 크지 않고 NUL 문자를 포함하지 않는 경우 다음을 수행할 수 있습니다.

grep -zPo 'pin\(ABC\) (\{([^{}]++|(?1))*\})' file

이들 ( pcregrepgrep -P)은 재귀 정규식 연산자를 지원하는 PCRE 모드를 사용합니다.

pcregrep -M여러 줄 모드를 켜고( pcregrep정규식을 일치시킬 때 필요에 따라 여러 줄을 가져올 수 있음) grep -z대신 레코드를 NUL로 구분하도록 지시합니다.철사.

위의 트릭은 (?1)연산자에 있습니다. 즉,내부 정규식첫 번째팔렌 그룹따라서 우리는 재귀적인 정규식을 가지고 있습니다: 우리는 0개 이상의 ( ) 중괄호가 아닌 문자 ( , 소유격 버전입니다 ) {의 시퀀스가 ​​뒤따르는 시퀀스와 일치합니다.*[^{}]+++++또는다시 외부 정규식 (...)( {뒤에...)을 사용합니다.

pcrepattern자세한 내용은 매뉴얼 페이지를 참조하십시오. 이것은 거기에 있는 예제에서 거의 그대로 복사되었습니다.

사용 perl:

perl -l -0777 -ne 'print $& while /pin\(ABC\) (\{([^{}]++|(?1))*\})/g'

( grep메모리의 전체 파일을 먹는 것과 같습니다).

관련 정보