development

쉘 스크립트를 사용하여 XML을 구문 분석하는 방법은 무엇입니까?

big-blog 2020. 12. 3. 08:08
반응형

쉘 스크립트를 사용하여 XML을 구문 분석하는 방법은 무엇입니까?


이 질문에 이미 답변이 있습니다.

shellscript를 사용하여 XML 파일을 구문 분석하는 가장 좋은 방법이 무엇인지 알고 싶습니다.

  • 손으로해야할까요?
  • 세 번째 계층 라이브러리가 있습니까?

이미 만들었 으면 어떻게 해냈는지 알려 주시면


xmllint를 시도해 볼 수 있습니다.

xmllint 프로그램은 명령 줄에 xmlfile로 지정된 하나 이상의 XML 파일을 구문 분석합니다. 선택한 옵션에 따라 다양한 유형의 출력을 인쇄합니다. XML 코드와 XML 파서 모두에서 오류를 감지하는 데 유용합니다.

--pattern 옵션을 사용하여 xpath로 XML 문서의 요소를 선택할 수 있습니다.

Mac OS X (Yosemite)에서는 기본적으로 설치됩니다.
Ubuntu에서 아직 설치되지 않은 경우 다음을 실행할 수 있습니다.apt-get install libxml2-utils


다음은 전체 작동 예입니다.
이메일 주소 만 추출하는 경우 다음과 같이 할 수 있습니다.
1) XML 파일 spam.xml이 다음과 같다고 가정합니다.

<spam>
<victims>
  <victim>
    <name>The Pope</name>
    <email>pope@vatican.gob.va</email>
    <is_satan>0</is_satan>
  </victim>
  <victim>
    <name>George Bush</name>
    <email>father@nwo.com</email>
    <is_satan>1</is_satan>
  </victim>
  <victim>
    <name>George Bush Jr</name>
    <email>son@nwo.com</email>
    <is_satan>0</is_satan>
  </victim>
</victims>
</spam>

2) 다음과 같은 짧은 bash 코드로 이메일을 받고 처리 할 수 ​​있습니다.

#!/bin/bash
emails=($(grep -oP '(?<=email>)[^<]+' "/my_path/spam.xml"))

for i in ${!emails[*]}
do
  echo "$i" "${emails[$i]}"
  # instead of echo use the values to send emails, etc
done

이 예의 결과는 다음과 같습니다.

0 pope@vatican.gob.va
1 father@nwo.com
2 son@nwo.com

중요 사항 :
심각한 문제에는이 기능을 사용하지 마십시오. 이 등, 장난 빠른 결과를 얻고, GREP 학습을위한 OK입니다하지만 당신은해야 확실히 (아래 미샤의 의견을 참조)을 찾아 배우고 생산을위한 XML 파서를 사용합니다.


xmlstarlet (Windows에서도 사용 가능)도 있습니다.

http://xmlstar.sourceforge.net/doc/xmlstarlet.txt


아무도 xmlsh 를 언급하지 않은 것에 놀랐습니다 . 사명 선언문 :

Unix Shells의 철학과 디자인에 기반한 XML 용 명령 줄 셸

xmlsh는 친숙한 스크립팅 환경을 제공하지만 특히 xml 프로세스 스크립팅에 맞게 조정되었습니다.

쉘과 유사한 명령 목록이 여기 에 제공 됩니다 .

나는 XML과 xed동등한 명령을 많이 사용하고 기반 검색 및 대체를 sed허용 XPath합니다.


sgrep을 시도하십시오 . 정확히 무엇을 하려는지는 명확하지 않지만 bash에서 XML 파서를 작성하려고 시도하지는 않을 것입니다.


xml_grep이 설치되어 있습니까? 일부 배포판에서는 Perl 기반 유틸리티 표준입니다 (CentOS 시스템에 사전 설치되어 제공됨). 정규식을 제공하는 대신 xpath 표현식을 제공합니다.


다소 새로운 프로젝트는 xml-cat, xml-cp, xml-cut, xml-grep, ...을 특징으로하는 xml-coreutils 패키지입니다.

http://xml-coreutils.sourceforge.net/contents.html


xpath를 사용해보십시오. XML 트리에서 요소를 구문 분석하는 데 사용할 수 있습니다.

http://www.ibm.com/developerworks/xml/library/x-tipclp/index.html


이것은 실제로 쉘 스크립트의 기능을 넘어서는 것입니다. 쉘 스크립트와 표준 Unix 도구는 라인 지향 파일을 구문 분석하는 데 문제가 없지만 XML에 대해 이야기하면 상황이 바뀝니다. 간단한 태그도 문제를 일으킬 수 있습니다.

<MYTAG>Data</MYTAG>

<MYTAG>
     Data
</MYTAG>

<MYTAG param="value">Data</MYTAG>

<MYTAG><ANOTHER_TAG>Data
</ANOTHER_TAG><MYTAG>

Imagine trying to write a shell script that can read the data enclosed in . The three very, very simply XML examples all show different ways this can be an issue. The first two examples are the exact same syntax in XML. The third simply has an attribute attached to it. The fourth contains the data in another tag. Simple sed, awk, and grep commands cannot catch all possibilities.

You need to use a full blown scripting language like Perl, Python, or Ruby. Each of these have modules that can parse XML data and make the underlying structure easier to access. I've use XML::Simple in Perl. It took me a few tries to understand it, but it did what I needed, and made my programming much easier.


Here's a function which will convert XML name-value pairs and attributes into bash variables.

http://www.humbug.in/2010/parse-simple-xml-files-using-bash-extract-name-value-pairs-and-attributes/


Here's a solution using xml_grep (because xpath wasn't part of our distributable and I didn't want to add it to all production machines)...

If you are looking for a specific setting in an XML file, and if all elements at a given tree level are unique, and there are no attributes, then you can use this handy function:

# File to be parsed
xmlFile="xxxxxxx"

# use xml_grep to find settings in an XML file
# Input ($1): path to setting
function getXmlSetting() {

    # Filter out the element name for parsing
    local element=`echo $1 | sed 's/^.*\///'`

    # Verify the element is not empty
    local check=${element:?getXmlSetting invalid input: $1}

    # Parse out the CDATA from the XML element
    # 1) Find the element (xml_grep)
    # 2) Remove newlines (tr -d \n)
    # 3) Extract CDATA by looking for *element> CDATA <element*
    # 4) Remove leading and trailing spaces
    local getXmlSettingResult=`xml_grep --cond $1 $xmlFile 2>/dev/null | tr -d '\n' | sed -n -e "s/.*$element>[[:space:]]*\([^[:space:]].*[^[:space:]]\)[[:space:]]*<\/$element.*/\1/p"`

    # Return the result
    echo $getXmlSettingResult
}

#EXAMPLE
logPath=`getXmlSetting //config/logs/path`
check=${logPath:?"XML file missing //config/logs/path"}

This will work with this structure:

<config>
  <logs>
     <path>/path/to/logs</path>
  <logs>
</config>

It will also work with this (but it won't keep the newlines):

<config>
  <logs>
     <path>
          /path/to/logs
     </path>
  <logs>
</config>

If you have duplicate <config> or <logs> or <path>, then it will only return the last one. You can probably modify the function to return an array if it finds multiple matches.

FYI: This code works on RedHat 6.3 with GNU BASH 4.1.2, but I don't think I'm doing anything particular to that, so should work everywhere.

NOTE: For anybody new to scripting, make sure you use the right types of quotes, all three are used in this code (normal single quote '=literal, backward single quote `=execute, and double quote "=group).

참고URL : https://stackoverflow.com/questions/4680143/how-to-parse-xml-using-shellscript

반응형