从xml输出中打印值

时间:2020-12-01 01:06:48

I am working on a script, which returns output in xml format and wanted to print just the value of a particular attribute.

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

As an example, here is the output of the script :

例如,下面是脚本的输出:

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

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

Now, I wanted to print only the Resource id which is 11087. When I used awk along with NR, it returns as below :

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

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

id="11087"

Could you please help know how to print only the value, i.e 11087

你能帮忙知道如何只打印值i吗?e 11087

4 个解决方案

#1


3  

Here is another solution using xmlstarlet with XPath query :

下面是另一个使用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

It's always better to use tools optimized for XML parsing (xmlstarter, xmllint, or more powerful shells languages ​​like perl, python, php cli mode, etc.).

最好使用为XML解析而优化的工具(xmlstarter、xmllint或更强大的shell语言,如perl、python、php cli mode等)。

#2


2  

Using sed:

使用sed:

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

Notes:

注:

  • The -n option to sed tells it not print anything unless we explicitly ask it to.

    sed的-n选项告诉它不打印任何内容,除非我们明确地要求它这样做。

  • The -r option to sed tells it to use extended regular expressions

    sed的-r选项告诉它使用扩展正则表达式

  • The sed command 4 s/old/new/p tells it to operate on only on line 4 and, on that line, look for old and replace it with new and, only if that substitution happened, print the line.

    sed命令4 s/old/new/p只告诉它在第4行上操作,在这一行中,查找旧的并使用new替换它,只有在发生替换时,打印行。

  • In our case, the value of old is .*id="([^"]+)".*/. Since this starts with .* and ends with .*, it matches the whole line. It also captures the value of the id in match variable 1.

    在我们的例子中,旧的价值。* id = "([^]+)。* /。因为它以。*开头,以。*结尾,所以它与整条线相匹配。它还捕获匹配变量1中的id值。

  • The value of new is simply \1 which is the value of the id.

    new的值只是\1,它是id的值。

#3


2  

This awk should give what you want.

这个awk应该给你想要的。

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

By setting Field Separator to " your data are in the second field.

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

To make sure you get correct id, I would have used:

为了确保您得到正确的id,我将使用:

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

#4


2  

grep variant:

grep变体:

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

Or with input piped from your command:

或使用来自命令的输入管道:

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

Explanation: Print only (-o) first match (-m1) of number ([0-9]*) prefixed by id=" ((?<=id=")) & followed by a " ((?=")).

说明:只打印(-o)第一次匹配(-m1)的数字([0-9]*),前缀为id=" ((?<=id="),后面是"(?=")。

#1


3  

Here is another solution using xmlstarlet with XPath query :

下面是另一个使用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

It's always better to use tools optimized for XML parsing (xmlstarter, xmllint, or more powerful shells languages ​​like perl, python, php cli mode, etc.).

最好使用为XML解析而优化的工具(xmlstarter、xmllint或更强大的shell语言,如perl、python、php cli mode等)。

#2


2  

Using sed:

使用sed:

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

Notes:

注:

  • The -n option to sed tells it not print anything unless we explicitly ask it to.

    sed的-n选项告诉它不打印任何内容,除非我们明确地要求它这样做。

  • The -r option to sed tells it to use extended regular expressions

    sed的-r选项告诉它使用扩展正则表达式

  • The sed command 4 s/old/new/p tells it to operate on only on line 4 and, on that line, look for old and replace it with new and, only if that substitution happened, print the line.

    sed命令4 s/old/new/p只告诉它在第4行上操作,在这一行中,查找旧的并使用new替换它,只有在发生替换时,打印行。

  • In our case, the value of old is .*id="([^"]+)".*/. Since this starts with .* and ends with .*, it matches the whole line. It also captures the value of the id in match variable 1.

    在我们的例子中,旧的价值。* id = "([^]+)。* /。因为它以。*开头,以。*结尾,所以它与整条线相匹配。它还捕获匹配变量1中的id值。

  • The value of new is simply \1 which is the value of the id.

    new的值只是\1,它是id的值。

#3


2  

This awk should give what you want.

这个awk应该给你想要的。

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

By setting Field Separator to " your data are in the second field.

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

To make sure you get correct id, I would have used:

为了确保您得到正确的id,我将使用:

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

#4


2  

grep variant:

grep变体:

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

Or with input piped from your command:

或使用来自命令的输入管道:

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

Explanation: Print only (-o) first match (-m1) of number ([0-9]*) prefixed by id=" ((?<=id=")) & followed by a " ((?=")).

说明:只打印(-o)第一次匹配(-m1)的数字([0-9]*),前缀为id=" ((?<=id="),后面是"(?=")。