从xml输出中打印值

时间:2014-05-21 05:09:31

标签: xml bash shell awk

我正在编写一个脚本,它以xml格式返回输出,并且只想打印特定属性的值。

举个例子,这是脚本的输出:

~#] ./test.sh resource list --platform=centos

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ResourcesResponse>
<Status>Success</Status>
<Resource id="11087" name="centos" 

现在,我想只打印资源ID为11087.当我使用awk和NR时,它返回如下:

~#] ./test.sh resource list --platform=centos | awk 'NR==4{print $2}'

id="11087"

请你帮忙知道如何只打印数值,即11087

4 个答案:

答案 0 :(得分:3)

以下是使用xmlstarlet和XPath查询的另一种解决方案:

$ ./test.sh resource list --platform=centos|xmlstarlet sel -T -t -m '/ResourcesResponse/Resource/@id' -v '.' -n
11087
$ xmlstarlet sel -T -t -m '/ResourcesResponse/Resource/@id' -v '.' -n < <(./test.sh resource list --platform=centos)
11087

使用针对XML解析优化的工具(xmlstarterxmllint或更强大的shell语言(如perl,python,php cli模式等)总是更好。

答案 1 :(得分:2)

awk应该提供您想要的内容。

awk -F\" 'NR==4{print $2}' file
11087

通过将字段分隔符设置为",您的数据位于第二个字段中。

为确保您获得正确的id,我会使用:

awk -F\" '/Resource id/ {print $2}' file
11087

答案 2 :(得分:2)

使用sed

~#] ./test.sh resource list --platform=centos | sed -nr '4 s/.*id="([^"]+)".*/\1/p'
11087

注意:

  • -n的{​​{1}}选项告诉它除非我们明确要求,否则不会打印任何内容。

  • sed的{​​{1}}选项告诉它使用扩展正则表达式

  • -r命令sed告诉它仅在第4行进行操作,并在该行上查找sed并将其替换为4 s/old/new/p, ,只有当替换发生时,打印该行。

  • 在我们的案例中,old的值为new。由于此操作以old开头,以.*id="([^"]+)".*/结尾,因此它与整行匹配。它还捕获匹配变量1中id的值。

  • .*的值只是.*,即id的值。

答案 3 :(得分:2)

grep变种:

grep -m1 -oP '(?<=id=")[0-9]*(?=")' file

或者输入管道输入:

~#] ./test.sh resource list --platform=centos | grep -m1 -oP '(?<=id=")[0-9]*(?=")' 
11087

说明: 仅打印(-o)第一个匹配(-m1)的数字([0-9]*),前缀为id="(?<=id="))&amp;然后是"(?="))。