Unix 명령을 사용하여 `xml`에서 빈 태그 찾기

Unix 명령을 사용하여 `xml`에서 빈 태그 찾기

생성된 파일에는 xml아래와 같이 빈 태그가 있습니다.

<headertag>
</headertag>

연속된 줄에 있고 태그 사이의 개행 문자를 패턴(\n)으로 기반으로 찾기 위해 보통 Perl 스크립트를 사용하지만, 지금 사용하고 있는 Unix 환경에서는 이 Perl 스크립트를 지원하지 않습니다. sed를 사용하여 동일한 작업을 시도했지만 .xml큰 파일에서 이러한 빈 표시가 있는 위치(줄 번호)를 찾을 수 없습니다 . sed또는를 사용하여 이를 찾을 수 있는 솔루션이 있습니까 awk?

답변1

XML을 구문 분석하려면 XML 인식 도구를 사용하십시오. 사용 중인 시스템에 제한이 있다고 말씀하신 것을 알고 있습니다. 그러나 강력하고 안정적인 작업을 위해 필요한 모든 것을 관리자에게 설득하면 작동할 수 있는 솔루션을 제공할 것입니다. XML 구문 분석을 올바르게 수행하려면 XMLStarlet을 설치해야 합니다.

주어진 XML 파일에서 XMLStarlet 사용

<?xml version="1.0"?>
<root>
  <headertag>
    <subtag/>
  </headertag>
  <headertag>
    <subtag>Don't delete me!</subtag>
  </headertag>
  <headertag>
</headertag>
  <headertag>
Not empty
</headertag>
</root>

다음은 이름이나 문서에 나타나는 위치에 관계없이 모든 빈 태그를 제거합니다.

$ xmlstarlet ed -d '//*[not(normalize-space())]' file.xml >newfile.xml

$ cat newfile.xml
<?xml version="1.0"?>
<root>
  <headertag>
    <subtag>Don't delete me!</subtag>
  </headertag>
  <headertag>
Not empty
</headertag>
</root>

이 명령은 시스템에 패키지된 방식에 따라 xmlstarlet호출될 수도 있습니다 .xml

XMLStarlet은 여기에서 사용할 수 있습니다:http://xmlstar.sourceforge.net/ ...하지만 먼저 기본 패키지 관리자에 해당 기능이 있는지 확인하세요.

답변2

가정:

  • 우리가 찾고 있는 빈 태그는 그 자체로 한 줄에 있습니다.
  • 닫는 태그도 자체 줄에 있고 바로 뒤에옵니다.
  • 공백은 탭이 아닌 공백으로 구성되는 것으로 간주됩니다.

sed -ne '
   /^ *\(<[^><]*>\) *$/!d                                   # tag opening should be on a line of its own
   s//\1/                                                   # strip away all whitespace
   $d; N                                                    # if the tag opening is on the last line, we dont need it. Otherwise, we grab the next line
   s/^.\(.*\).\n *<\/\1> *$/Empty tag: <\1> on line num\#/p # print only in case the tagnames match across lines => we have found an empty tag
   /\n/!=                                                   # print empty tag line num
   D                                                        # delete the pattern space
' yourfile.xml

답변3

빈 태그를 처리하는 방법을 알려주지 않았습니다. 따라서 이러한 태그 쌍을 다음 형식으로 변환하고 싶다고 가정합니다.<headertag/>

sed다음은 귀하가 제공한 예제 사례에 대해 정확히 해당 작업을 수행하는 간단한 스크립트입니다 .

sed -E ':a;N;$!ba;s#<([^>]+)>\n</\1>#<\1/>#g' infile > outfile

답변4

grep 대신 "pcregrep"을 사용할 수 있으며 여러 줄 모드를 지원하고 더 많은 옵션이 있습니다.

이 패턴은 시작 태그와 끝 태그가 포함된 두 개의 연속 라인을 찾습니다.

pcregrep -M -v "<headertag>\n\s*?</headertag>" file
  • 여기서 -M은 여러 줄을 나타냅니다.
  • -v는 역방향 일치를 나타냅니다.
  • \n은 pcregrep에서는 지원되지만 grep에서는 지원되지 않는 개행 문자입니다.
  • \s는 공백 문자입니다.
  • *? 모든 문자

이 모드는 빈 태그를 모두 제거합니다.

관련 정보