개행/개행/개행 문자가 포함된 문자열을 Unix에서 파일 검색

개행/개행/개행 문자가 포함된 문자열을 Unix에서 파일 검색

파일에서 문자열(문자열에는 개행/개행이 포함됨)을 검색하고 패턴 일치 후 2줄을 인쇄합니다. 예를 들어 파일에 다음이 포함되어 있습니다. - (편집됨)

           <cfu>
              <statm1>
              <status>good</status>
           </cfu>
           <cfu>
              <statm2>
              <status>not found</status>
           </cfu>
           <cfu>
              <statm3>
              <status>empty</status>
           </cfu>
           <cfa>
              <statm1>
              <status>good</status>
           </cfa>
           <cfa>
              <statm2>
              <status>not found</status>
           </cfa>
           <cfa>
              <statm3>
              <status>empty</status>
           </cfa>
              
           

나는 다음과 같은 것을 시도했습니다

awk -v RS=""'/<cfu> <statm1/{i=NR+2}(NR<=i){print}' file_name

하지만 운이 없어요 도와주세요

예상 출력:-

           <cfu>
              <statm1>
              <status>good</status>
           </cfu>

답변1

XML을 디코딩하지 않고(어쨌든 입력이 XML과 정확히 일치하지 않음) pcregrepultiline M모드를 사용하십시오.

$ pcregrep -Mo '(?s)<cfu>(?:(?!</cfu>).)*<statm1>.*?</cfu>' your-file
<cfu>
              <statm1>
              <status>good</status>
           </cfu>
  • (?s)개행 문자도 일치 s시키는 플래그를 켭니다 ..
  • (?!</cfu>)..앞에 문자( )가 없습니다 </cfu>. 우리는 match 0 이상을 사용합니다 *. 대신 .*다음 종료 시간을 초과하지 않도록 하기 위해 이것을 사용합니다 </cfu>.
  • *?예, 탐욕스럽지 않은 버전입니다 *.

값만 원하는 경우 <status>:

$ pcregrep -Mo1 '(?s)<cfu>(?=(?2)*<status>([^<]*))((?!</cfu>).)*<statm1>.*?</cfu>' your-file
good

답변2

root파일을 노드로 둘러싼 후 올바른 HTML/XML 구문 분석기를 사용합니다 .

그리고 xidel:

xidel --output-node-format=xml -e '//cfu[contains(., "good")]' file

산출:

<cfu>
          <statm1>
          <status>good
       </status></statm1></cfu>

그리고 xmlstarlet:

xmlstarlet format -H file | sponge file
xmlstarlet sel -t -c '//cfu[contains(., "good")]' file 2>/dev/null

산출:

<cfu>
          <statm1>
          <status>good
       </status></statm1></cfu>

관련 정보