如何使用shell脚本parsingXML?

我想知道什么是使用shell脚本parsingXML文件的最佳方法?

  • 应该手动吗?
  • 第三层图书馆是否存在?

如果你已经做到了,如果你能让我知道你是如何做到的

你可以试试xmllint

xmllint程序将一个或多个XML文件(在命令行中指定为xmlfile)parsing。 它根据select的选项打印各种types的输出。 这对检测XML代码和XMLparsing器中的错误非常有用

它允许您使用–pattern选项通过xpathselectXML文档中的元素。

在Mac OS X(优胜美地)上,默认安装。
在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等是可以的,但是您一定要查找,学习和使用XMLparsing器进行生产(请参阅下面的Micha的评论)。

还有xmlstarlet(也可用于Windows)。

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

我很惊讶没有人提到过xmlsh 。 使命宣言:

XML的命令行shell基于Unix Shell的原理和devise

xmlsh提供了一个熟悉的脚本环境,但专门为脚本xml进程量身定做。

这里提供了一个类似shell的命令列表。

我使用了很多相当于sed for XML的xed命令,并允许基于XPath的search和replace。

试试sgrep 。 目前还不清楚你正在尝试做什么,但我肯定不会尝试在bash中编写XMLparsing器。

你有没有安装xml_grep? 这是基于perl的一些发行版的实用标准(它是在我的CentOS系统上预先安装的)。 而不是给它一个正则expression式,你给它一个xpathexpression式。

一个相当新的项目是xml-coreutils包,包含xml-cat,xml-cp,xml-cut,xml-grep,…

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

尝试使用xpath。 您可以使用它来parsingxml树中的元素。

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

这实际上超出了shell脚本的function。 Shell脚本和标准的Unix工具在parsing面向行的文件上是可以的,但是当谈论XML的时候事情就会改变。 即使简单的标签也会出现问题:

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

想象一下,试图编写一个可以读取数据的shell脚本。 这三个非常简单的XML示例都显示了不同的方式,这可能是一个问题。 前两个例子是XML中完全相同的语法。 第三个简单地有一个属性附加到它。 第四个包含另一个标签中的数据。 简单的sedawkgrep命令不能捕捉所有的可能性。

您需要使用完整的脚本语言,如Perl,Python或Ruby。 其中的每个模块都可以parsingXML数据,并使底层结构更易于访问。 我在Perl中使用XML :: Simple 。 我花了几次尝试去理解它,但是它做了我所需要的,并且使我的编程更容易。

这是一个将XML名称 – 值对和属性转换成bashvariables的函数。

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

这是一个使用xml_grep的解决scheme(因为xpath不是我们可分发的一部分,我不想把它添加到所有的生产机器)。

如果您正在查找XML文件中的特定设置,并且给定树级别的所有元素都是唯一的,并且没有属性,那么您可以使用这个方便的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"} 

这将与这个结构一起工作:

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

它也将与此(但它不会保留换行符):

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

如果有重复的<config>或<logs>或<path>,那么它只会返回最后一个。 如果find多个匹配项,您可以修改该函数以返回一个数组。

仅供参考:此代码适用于GNU BASH 4.1.2的RedHat 6.3,但我不认为我正在做什么特别的事情,所以应该到处工作。

注意:对于任何不熟悉脚本的人,确保使用正确types的引号,这三个代码都用在这个代码中(普通单引号'= literal,反引号'= execute'和双引号'= group')。