<source file='/home/anpham/Projects/vm-builder/30G'/>

I tried to use sed command to extract the absolute path from the output above but the output doesn't trim the string. The following commands is my attempt.

virsh dumpxml --domain "test1" | grep 'source file' | head -1 | sed '/^<source$/d' 

The Output is still:

<source file='/home/anpham/Projects/vm-builder/30G'/>

3 Answers 3


To extract the value of all file attributes of all source nodes in an XML document, you may use xmlstarlet like this:

xmlstarlet sel -t -v '//source/@file' -nl file.xml

Or, reading from your virsh command:

virsh dumpxml --domain "test1" | xmlstarlet sel -t -v '//source/@file' -nl

The issue with your pipeline is that the final sed command tries to delete all lines that consist of the exact string <source (and nothing else). You don't have such lines in the input to sed.

  • Work as expected, but xmlstartlet must be installed. I still like this solution since it provides simplicity. Mar 4, 2020 at 8:30
  • 3
    @vincentpham You're already using virsh which is another program that I'm presuming "must be installed". You could just install xmlstarlet together with virsh whenever you're doing a new installation (just like installing jq when you install any other utility that produces JSON output).
    – Kusalananda
    Mar 4, 2020 at 8:55
  • my current system prompt me to install xmlstarlet. Since I'm building a bash script from virsh, installing extra packages is not really preferred. In short, @Ed Morton's answer would be a safer approach to produce sufficient output. Mar 5, 2020 at 1:18
  • 1
    @vincentpham It's entirely your own call, obviously.
    – Kusalananda
    Mar 5, 2020 at 6:59

With any sed in any shell on every UNIX box:

$ sed "s/.*<source file='\([^']*\).*/\1/" file
  • I edit the answered to my need. Mar 5, 2020 at 1:19

First: your sed command will never match anything but a line which only contents the word source. This is because you put ^ (begin of line) right before and $ (end of line) right after the word source. Second: it can be done without grep and head:

virsh dumpxml --domain "test1" | sed -ne 's/\s*<source file=.\([^\/].*\).\/>.*/\1/; t end; b; :end; p; Q'
  • I still have some spaces at the beginning. Mar 4, 2020 at 8:28
  • modified the answer to accommodate white spaces at the beginning of the line.
    – bey0nd
    Mar 4, 2020 at 8:53

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .