Reputation: 2815
I am working on a script, which returns output in xml format and wanted to print just the value of a particular attribute.
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 :
~#] ./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
Upvotes: 1
Views: 390
Reputation: 3838
Here is another solution using xmlstarlet
with XPath query :
$ ./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.).
Upvotes: 3
Reputation: 20980
grep variant:
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 "
((?=")
).
Upvotes: 2
Reputation: 41460
This awk
should give what you want.
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:
awk -F\" '/Resource id/ {print $2}' file
11087
Upvotes: 2
Reputation: 113884
Using 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.
The -r
option to sed
tells it to use extended regular expressions
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.
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.
The value of new
is simply \1
which is the value of the id.
Upvotes: 2