0

我需要从 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 或命令的解决方案来访问代码行中的路径属性。

我试过类似的东西

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
4

2 回答 2

1

由于这些事情通常发生,此命令高度依赖于您的输入

$ awk '/path/ {print $4}' FS='"' file.xml
//HEP/jcas/kpreader/trunk/...
于 2013-06-26T11:25:03.973 回答
0

您基本上可以使用 grep 之类的 xpath “排序”。对于这种情况,我会使用

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

如果您需要考虑像 /p4codeline/module/codeline/@path 这样的 xpath。您需要将文件转换为单行输入并通过管道传输到一些 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

猫文件.xml | anjopath.sh /p4codeline/module/codeline/rules

于 2019-08-08T09:39:07.903 回答