2016-06-08 35 views
0

我使用下面的XML文件shell脚本来搜索特定字符串

<?xml version="1.0" encoding="UTF-8"?> 
<log> 
    <logentry revision="31"> 
     <date>2016-06-07</date> 
     <paths> 
      <path kind="file" action="M">components/C_MyAccountChangePassword.component</path> 
     </paths> 
     <msg>R002</msg> 
    </logentry> 
    <logentry revision="26"> 
     <date>2016-06-07</date> 
     <paths> 
      <path kind="file" action="M">applications/Admin_Util.app</path> 
     </paths> 
     <msg>R001 added comments</msg> 
    </logentry> 
</log> 

我必须寻找一个字符串像

grep "R001" 

和我后得到的XML元素的值需要获取<path>标签中提到的文件。任何人都可以帮助我如何实现它。我曾试过几件东西,如

grep -A1 "<msg>R001" log.xml | grep "<path>" 

但没有得到所需的输出。

+0

是每个XML标签上一个新行作为'edit'忽略新线或你有全部在一个行你早些时候粘贴? – Utsav

回答

0

正如指出的Stefan Hegnygrep可能不是应对来自xml标签中提取数据的最佳方式,但如果你是明确的有关文件作为OP的格式(如换行分隔的条目)您可以使用以下逻辑: -

grep -B 3 -w "R001" file | awk -F '[<>]' '/path/{print $3}' 

将产生一个输出applications/Admin_Util.app

的逻辑是让搜索的模式,并根据需要才提取n线和部署awk做休息。如果你有兴趣的值存储在脚本中的变量,你可以使用tr

#!/bin/bash 
xmlContent=$(grep -B 3 -w "R001" file | awk -F '[<>]' '/path/{print $3}' | tr -d '\n') 
+0

非常感谢您的帮助 –

0

使用grep with xml通常不是一个好主意。我建议你使用适当的工具,如xslt或xmllint(从libxml

你可能会

xmllint --xpath '//logentry[contains(msg,"R001")]/paths/path' your.xml 

,并得到

<path kind="file" action="M">applications/Admin_Util.app</path> 

可以更容易进行后处理,或使用xsltproc的(也libxml/libxslt)使用XSLT样式表使输出适合您需要的形状。

如果你的xml确实是格式化的,并且所有的<logentry>都在一行中,那么基于正常的基于句法正则表达式的方法可能是可行的,但是在一般情况下,例如,就像你的样品一样,所有这一切都在一条线上,结果很难。