访问bash脚本中的xml属性

时间:2013-06-26 09:26:02

标签: xml linux bash

我需要从bash脚本中的xml文件中获取属性,但我既不能使用xmllint --xpath也不能使用xmlstarlet,因为它们在我工作的服务器上不可用。

我尝试过使用grep,cut和sed的解决方案,但这在很长一段时间内都不是一个好的解决方案。

机器上有grep_xml,我可以用它访问元素但是当我试图访问我的属性时,我得到了 "错误无法识别处理程序"

中的表达式

这是我的xml文件

<?xml version="1.0" standalone="yes"?>
<p4codeline xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="p4codeline_1_1.xsd">
  <module name="kpreader" currentVersion="kpreader_1.1STD0" previousVersion="kpreader_1.0STD0">
    <codeline owner="undefined" path="//HEP/jcas/kpreader/trunk/...">
      <namingConvention/>
      <description>Main codeline for development</description>
      <rules>
        <rule>Develop on MAIN, and create a TAG codeline on release</rule>
        <rule>Never broke the build on the MAIN</rule>
      </rules>
    </codeline>
    <externals>
      <external viewPath="J2ep_BuildTools/..." codeLine="//CT/JAVA/J2ep_BuildTools/Source/tags/J2EP_BUILDTOOLS_1.6STD0/..." depotPath="."/>
    </externals>
  </module>
</p4codeline>

我只需要使用基于bash或命令的解决方案来访问代码行中的path属性。

我尝试过像

这样的事情
xml_grep -t '/p4codeline/module/codeline/@path' file.xml

它让我感到厌烦

error: unrecognized expression in handler: '/p4codeline/module/codeline@path' at /usr/bin/xml_grep line 183

2 个答案:

答案 0 :(得分:1)

通常情况下,此命令高度依赖于您的输入

$ awk '/path/ {print $4}' FS='"' file.xml
//HEP/jcas/kpreader/trunk/...

答案 1 :(得分:0)

您基本上可以像xpath“ sort of”一样使用grep。在这种情况下,我将使用

grep  -oP "(?<=[<]codeline)[^<]+" file.xml |  grep  -oP "(?<=path\=\")[^\"]*"

如果需要考虑xpath,例如/ p4codeline / module / codeline / @ path。您需要将文件转换为单行输入,并通过管道传递到某些grep语句

tr -d '\n' <  file.xml | grep -Eo '<p4codeline .+/p4codeline>' | grep -Eo '<module .+/module>' |  grep  -oP "(?<=[<]codeline)[^<]+" | grep  -oP "(?<=path\=\")[^\"]*"

将其放在一个小的bash脚本中

#!/usr/bin/env bash
if [ -p /dev/stdin ]
  then
    xmlinput=`cat | tr -d '\n'`
else 
 xmlinput=`tr -d '\n' < ${1}`
fi

if [[ ${2} == "" ]]
 then
   ajpath="${1}/EOP"
else
  ajpath="${2}/EOP"
fi

echo "${ajpath}" | tr '/' '\n' | while read i
 do
# if first letter is @ look for attribute
if [[ "$i" == "EOP" ]]
  then
   echo $xmlinput
   break
fi
if [[ "${i:0:1}" == "@" ]]
  then
   xmlinput=`echo $xmlinput | grep  -oP "(?<=${i#?}\=\")[^\"]*"`
  else
  if [[ "$i" != "" ]]
   then
   xmlinput=`echo $xmlinput | grep -Eo "<${i}.+/${i}>"`
  fi
fi
done

您执行 anjopath.sh file.xml / p4codeline / module / codeline / @ path

之类的脚本

将为您提供 // HEP / jcas / kpreader / trunk /...

anjopath.sh file.xml / p4codeline / module / @ name

将为您提供 kpreader

anjopath.sh file.xml / p4codeline / module / codeline / rules

会给您

> <rules> <rule>Develop on MAIN, and create a TAG codeline on
> release</rule> <rule>Never broke the build on the MAIN</rule> </rules>

您也可以像这样通过管道xmlinput

cat file.xml | anjopath.sh / p4codeline / module / codeline / rules