Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I have the following bash command which fetches and block XML from a single column in mysql and feeds it into xmllint to prettify it.

mysql --format csv --skip-column-names -e "select xmldata from mytable limit 1;" | xmllint --format -

So far so good, but it only works for one row at a time. I would like to adapt this so each line in the SQL query output is fed in to a separate call to xmlint.

I know this can be done with a loop in a bash script -- but I'd like to do it in a one-liner if possible. Supposedly this can be done with xargs but I can't figure it out.

share|improve this question
up vote 6 down vote accepted
mysql --format csv --skip-column-names \
    -e "select xmldata from mytable limit 1;" \
    | while IFS= read -r line; do xmllint --format - <<<"$line"; done

Split for easier reading, obviously you don't need to. The <<<$line is a herestring, which feeds the contents of $line to xmllint as stdin.

share|improve this answer
+1 for herestring, I've always done this as while read line; do echo $line | xmllint... – Kyle Smith Feb 8 '12 at 22:18
Previously the last line of the answer was written: while read line; do xmllint --format - <<<$line; done ... that worked fine for me... why was it changed and what's the difference? – frankadelic Feb 9 '12 at 3:44
@frankadelic it's almost always best to quote a variable when you use it, so Gilles added quotes here. – Kevin Feb 9 '12 at 3:51
Right, but why was IFS= added? And what is read -r ? – frankadelic Feb 9 '12 at 3:53
@gilles before I posted, I checked and it didn't break on anything I could find without the quotes. Can you give an example that breaks an unquoted herestring? – Kevin Feb 9 '12 at 3:53

This is possible with xargs, but xargs would pass each line as an argument to xmllint, not on its standard input. You would need to have xargs invoke a shell to feed the text to xmllint.

mysql … | xargs -L 1 sh -c 'echo "$0" | xmllint --format -'

A shell loop is the easiest method. The canonical way to loop over lines is while IFS= read -r line; do ….

mysql … |
while IFS= read -r line; do printf '%s\n' "$line" | xmllint --format -; done
share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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