使用重击,
文件:
<?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 数据。和xmlstarlet它只是成为一个 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 的艺术有更多的了解,所以我准备好接受一些批评:-)