파일에서 문자열(문자열에는 개행/개행이 포함됨)을 검색하고 패턴 일치 후 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과 정확히 일치하지 않음) pcregrep
ultiline 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>