6

We want to read XML attributes from an XML file. Example of file content is as below:

<properties>
  <property name="abc" value="15"/>
  <property name="xyz" value="26"/>
</properties>

We want to read value (i.e. 15) for property "abc" using shell script.
Please suggest shell commands to achieve this.

3
  • What have you tried so far ? What exactly do you want ? A function that returns 15 if you call func(abc) ? or a function that will parse your file and return abc 15, xyz 26, ... ? Commented Aug 26, 2014 at 15:00
  • it's better to use a xml parser rather than sed or awk. Commented Aug 26, 2014 at 15:01
  • You can have a look at xmlstarlet to parse XML files, it has support for XPath. Commented Aug 26, 2014 at 15:10

3 Answers 3

9

You can use a proper XML parser like xmllint. If your version supports xpath, it will be very easy to grab specific values. If it doesn't support xpath, then you can use --shell option like so:

$ echo 'cat //properties/property[@name="abc"]/@value' | xmllint --shell myxml
/ >  -------
 value="15"
/ > 

You can then use awk or sed to format and extract desired field from output.

$ echo 'cat //properties/property[@name="abc"]/@value' | xmllint --shell myxmlfile | awk -F'[="]' '!/>/{print $(NF-1)}'
15

You can use command substitution to capture the output in a variable by saying:

$ myvar=$(echo 'cat //properties/property[@name="abc"]/@value' | xmllint --shell myxml | awk -F'[="]' '!/>/{print $(NF-1)}')
$ echo "$myvar"
15

Using anything else other than a xmlparser is prone to errors and will break easy.

Sign up to request clarification or add additional context in comments.

Comments

1

quick and dirty

sed -n '/<Properties>/,\|</properties>| {
   s/ *<property name="xyz" value="\([^"]*\)"\/>/\1/p
   }'

no xml check and based on your sample so assume same structure (one property name per line, ...)

posix version (--posix for GNU sed)

Comments

1

sed -n '/<property name="abc"/s/.*value="\(.*\)"[^\n]*/\1/p' file

Creates a hold pattern for the value then matches everything except for the newline to avoid printing the newline, it expects the value double quoted as per your example data.

E.g. 
<properties>
  <property name="abc" value="15"/>
  <property name="xyz" value="26"/>
</properties>

Output:
15

(Prior to edit: sed '/<property name="abc"/s/.*value="\(.*\)"[^\n]*/\1/' file)

2 Comments

This is not working it gives output as <properties> 15 <property name="xyz" value="26"/> </properties>
My error, it should have print and -n on there: sed -n '/<property name="abc"/s/.*value="(.*)"[^\n]*/\1/p' file

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.