从 XML 中提取属性值

从 XML 中提取属性值

使用重击,

文件:

<?xml version="1.0" encoding="UTF-8"?>
<blah>
    <blah1 path="er" name="andy" remote="origin" branch="master" tag="true" />
    <blah1 path="er/er1" name="Roger" remote="origin" branch="childbranch" tag="true" />
    <blah1 path="er/er2" name="Steven" remote="origin" branch="master" tag="true" />

</blah>

我已经尝试过以下方法:

grep -i 'name="andy" remote="origin" branch=".*\"' <filename>

但它返回整行:

<blah1 path="er" name="andy" remote="origin" branch="master" tag="true" />

我想根据以下内容来匹配该行:

name="andy"

我只是想让它返回:

master

答案1

使用 XML 解析器来解析 XML 数据。和它只是成为一个 XPath 练习:

$ branch=$(xmlstarlet sel -t -v '//blah1[@name="andy"]/@branch' file.xml)
$ echo $branch
master

答案2

grep

grep -Pio 'name="andy".*branch="\K[^"]*' file
  • -P启用 Perl 正则表达式 (PCRE)
  • -i忽略大小写
  • -o只打印匹配的部分

在正则表达式中,\K是零宽度后向查找,用于匹配 之前的部分\K,但不将其包含在匹配中。

答案3

使用 xmllint 通过 XPath 提取属性的值:

xmllint --xpath 'string(/blah/blah1[@name="andy"]/@branch)' file.xml

最好使用 XML 解析器来处理 XML,因为属性的顺序可能会更改,并且可能会插入换行符,从而导致名称和分支属性位于文件的不同行中。

答案4

我认为这有效:

$ grep -i 'name="andy" remote="origin" branch=".*\"' <filename> | awk -F' ' '{print $5}' | sed -E 's/branch=\"(.*)\"/\1/'
master

awk部分确保仅branch="master"返回,该sed部分返回双引号之间的内容和引用(\1与括号之间的部分匹配)。

现在我知道这里有很多人对 awk 和 sed 的艺术有更多的了解,所以我准备好接受一些批评:-)

相关内容