조건에 따라 xml 파일에서 텍스트 블록 추출

조건에 따라 xml 파일에서 텍스트 블록 추출

fqdns다음 파일에서 콘텐츠를 추출하고 싶지만 device위치별로만 가능합니다.statusnew

<device id='10.72.48.215'>
    <address>10.72.48.215</address>
    <status>old</status>
    <fqdns>10.72.48.215</fqdns>
    <parent></parent>
    <type>Unknown</type>
    <ports>
    </ports>
    <operatingsystems>
    </operatingsystems>
</device>
<device id='10.72.48.216'>
    <address>10.72.48.216</address>
    <status>new</status>
    <fqdns>10.72.48.216</fqdns>
    <parent></parent>
    <type>Unknown</type>
    <ports>
    </ports>
    <operatingsystems>
    </operatingsystems>
</device>

10.72.48.216그래서 위의 경우 (대신 ) 을 얻고 싶습니다 10.72.48.215.

답변1

XML 선언을 추가하고 device최상위 요소에 두 요소를 모두 포함하는 경우 XPath를 사용하여 파일을 처리할 수 있습니다.

$ cat ./248127.xml
    <device id='10.72.48.215'>
            <address>10.72.48.215</address>
            <status>old</status>
            <fqdns>10.72.48.215</fqdns>
            <parent></parent>
            <type>Unknown</type>
            <ports>
            </ports>
            <operatingsystems>
            </operatingsystems>
    </device>
    <device id='10.72.48.216'>
            <address>10.72.48.216</address>
            <status>new</status>
            <fqdns>10.72.48.216</fqdns>
            <parent></parent>
            <type>Unknown</type>
            <ports>
            </ports>
            <operatingsystems>
            </operatingsystems>
    </device>

$ ( echo '<?xml version="1.0"?><doc>'; cat ./248127.xml ; echo '</doc>' ) \
    | xpath -q -e '//device[status/text()="new"]/fqdns'
<fqdns>10.72.48.216</fqdns>

답변2

여러 줄 검색 옵션이 있는 pcrgrep 명령을 사용하여 이 작업을 수행할 수 있습니다.

pcregrep -M "\<status.*\n.*fqdns\>$"

귀하가 요청한 설명은 다음과 같습니다.

따라서 -M은 여러 줄을 의미합니다.

\< 문자열 시작 부분의 상태입니다. <의 의미를 알아내려면 \를 사용해야 합니다. 왜냐하면 이것은 쉘에 특별하기 때문입니다.

그 다음에. (모든 문자) 뒤에 *가 있으면 반복될 수 있음을 의미합니다.

\n 개행

. *가 뒤에 오는 문자의 경우 반복될 수 있기 때문입니다.

그런 다음 문자열 fqdns

그리고 닫아라

\>는 >입니다. 다시 \를 사용하여 의미를 표현합니다.

마지막으로 $는 줄의 끝입니다.

문자열 일치를 정규식이라고 합니다.

https://en.wikipedia.org/wiki/Regular_expression

답변3

간단한grep다음과 같이 할 수 있습니다.

grep -A1 "<status>new" sample.xml 
# <status>new</status>
# <fqdns>10.72.48.216</fqdns>

이는 XML 소스가 안정적이고 줄 순서를 변경하지 않는 경우에만 권장됩니다. (두 번째 블록에 "new"가 포함되도록 예제를 수정했습니다.)

more grep을 사용하여 다음 줄을 필터링할 수 있습니다.

grep -A1 "<status>new" sample.xml | grep "<fqdns>" 
# <fqdns>10.72.48.216</fqdns>

그리고sed, IP를 쉽게 추출할 수 있습니다.

sed -rn '/<status>new/{n; s/.*<fqdns>(.*)<\/fqdns>/\1/p}' sample.xml
# 10.72.48.216

일치 <status>new하고 읽혀 요N아웃라인과에스대체 태그와 닫는 태그 <fqdns>사이의 섹션입니다 . 이것-Nsed에게 "기본적으로 인쇄하지 않음", "-r"을 지정하면 마스킹 없이 정규식을 작성할 수 있습니다(여기서는 .* 주위의 괄호).

관련 정보