1

My xml file is in the below format. I want to get the value between <fullName>..</fullName> tags say ABC and DEF. I am writing this in a while loop to reach each line as I need the value of fullName of each xml tag to be taken in another variable. grep will display all values together.

Thanks

<fields>
    <fullName>ABC</fullName>
    <trackFeedHistory>false</trackFeedHistory>
    <type>TY</type>
</fields>

<fields>
    <fullName>DEF</fullName>
    <trackFeedHistory>false</trackFeedHistory>
    <type>XY</type>
</fields>
4

Use an xml parser, e.g. xmlstarlet:

xmlstarlet sel -t -m '//fields' -v 'fullName' -n file

Note that your xml file should be valid, which it is not for your example as your missing a root tag. The following will work with above command:

<root>
<fields>
    <fullName>ABC</fullName>
    <trackFeedHistory>false</trackFeedHistory>
    <type>TY</type>
</fields>

<fields>
    <fullName>DEF</fullName>
    <trackFeedHistory>false</trackFeedHistory>
    <type>XY</type>
</fields>
</root>

Output:

ABC
DEF

Thanks to @roaimas comment, I created a for loop with the results from xmlstarlet without knowing the number of fields:

numFields=$(xmlstarlet sel -t -m '//fields' -o "." file | wc -c)
for i in $(seq 1 $numFields); do
    var=$(xmlstarlet sel -t -m "//fields[$i]" -v "fullName" file)
    printf '%s\n' "$var" # or do something else
done
  • 1
    @user343860 to pick out each item separately you can qualify the //fields search with [1], [2], etc. For example xmlstarlet sel -t -m '//fields[2]' -v 'fullName' -n file will pick out the second match, DEF. – roaima Apr 9 at 15:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.