You could try xmllint

The xmllint program parses one or more XML files, specified on the command line as xmlfile. It prints various types of output, depending upon the options selected. It is useful for detecting errors both in XML code and in the XML parser itse

It allows you select elements in the XML doc by xpath, using the --pattern option.

On Mac OS X (Yosemite), it is installed by default.
On Ubuntu, if it is not already installed, you can run apt-get install libxml2-utils

Answer from Joel on Stack Overflow
Top answer
1 of 10
102

You could try xmllint

The xmllint program parses one or more XML files, specified on the command line as xmlfile. It prints various types of output, depending upon the options selected. It is useful for detecting errors both in XML code and in the XML parser itse

It allows you select elements in the XML doc by xpath, using the --pattern option.

On Mac OS X (Yosemite), it is installed by default.
On Ubuntu, if it is not already installed, you can run apt-get install libxml2-utils

2 of 10
25

Here's a fully working example.

If it's only extracting email addresses you could do something like:

  1. Suppose XML file spam.xml is like

    <spam>
    <victims>
      <victim>
        <name>The Pope</name>
        <email>[email protected]</email>
        <is_satan>0</is_satan>
      </victim>
      <victim>
        <name>George Bush</name>
        <email>[email protected]</email>
        <is_satan>1</is_satan>
      </victim>
      <victim>
        <name>George Bush Jr</name>
        <email>[email protected]</email>
        <is_satan>0</is_satan>
      </victim>
    </victims>
    </spam>
    
  2. You can get the emails and process them with this short bash code:

    #!/bin/bash
    emails=($(grep -oP '(?<=email>)[^<]+' "/my_path/spam.xml"))
    
    for i in ${!emails[*]}
    do
      echo "$i" "${emails[$i]}"
      # instead of echo use the values to send emails, etc
    done
    

The result of this example is:

0 [email protected]
1 [email protected]
2 [email protected]

Important note:
Don't use this for serious matters. This is OK for playing around, getting quick results, learning to grep, etc. but you should definitely look for, learn and use an XML parser for production (see Micha's comment below).

🌐
Opensource.com
opensource.com › article › 21 › 7 › parse-xml-linux
Use XMLStarlet to parse XML in the Linux terminal | Opensource.com
July 16, 2021 - You can view the data in XML with the xmlstarlet select (sel for short) command.
Discussions

command line - Parse XML to get node value in bash script? - Unix & Linux Stack Exchange
You can make use of php command line interface coding in bash scripts to handle several complex scripts that actually span over multiple lines of coding. First, try to make your solution using PHP scripts, and then later on pass the parameters using CLI mode. Thus, you can get control over superb usages of XML parsers... More on unix.stackexchange.com
🌐 unix.stackexchange.com
July 17, 2013
windows - How to parse a XML file with Command Line (cmd/batch) - Stack Overflow
I have a XML file Testing.Config with the following content: More on stackoverflow.com
🌐 stackoverflow.com
Parsing XML using unix terminal - Stack Overflow
Sometimes I need to quickly extract some arbitrary data from XML files to put into a CSV format. What's your best practices for doing this in the Unix terminal? I would love some code examples, so ... More on stackoverflow.com
🌐 stackoverflow.com
XML processor similar to jq
Have you looked at xmlstarlet (particularly the select subcommand), dasel , or petl ? More on reddit.com
🌐 r/commandline
10
11
October 27, 2020
🌐
GitHub
github.com › ericchiang › xpup
GitHub - ericchiang/xpup: A command line XML parsing tool
$ curl -s http://www.xmlfiles.com/examples/note.xml | xpup '/*/body' Don't forget me this weekend!
Starred by 71 users
Forked by 7 users
Languages   Go 100.0% | Go 100.0%
Top answer
1 of 9
26

Using bash and xmllint (as given by the tags):

xmllint --version  #  xmllint: using libxml version 20703

# Note: Newer versions of libxml / xmllint have a --xpath option which 
# makes it possible to use xpath expressions directly as arguments. 
# --xpath also enables precise output in contrast to the --shell & sed approaches below.
#xmllint --help 2>&1 | grep -i 'xpath'

{
# the given XML is in file.xml
host="$(echo "cat /config/global/resources/default_setup/connection/host/text()" | xmllint --nocdata --shell file.xml | sed '1d;$d')"
username="$(echo "cat /config/global/resources/default_setup/connection/username/text()" | xmllint --nocdata --shell file.xml | sed '1d;$d')"
password="$(echo "cat /config/global/resources/default_setup/connection/password/text()" | xmllint --nocdata --shell file.xml | sed '1d;$d')"
dbname="$(echo "cat /config/global/resources/default_setup/connection/dbname/text()" | xmllint --nocdata --shell file.xml | sed '1d;$d')"
printf '%s\n' "host: $host" "username: $username" "password: $password" "dbname: $dbname"
}

# output
# host: localhost
# username: root
# password: pass123
# dbname: testdb

In case there is just an XML string and the use of a temporary file is to be avoided, file descriptors are the way to go with xmllint (which is given /dev/fd/3 as a file argument here):

set +H
{
xmlstr='<?xml version="1.0"?>
<config>
    <global>
        <install>
            <date><![CDATA[Tue, 11 Dec 2012 12:31:25 +0000]]></date>
        </install>
        <crypt>
            <key><![CDATA[70e75d7969b900b696785f2f81ecb430]]></key>
        </crypt>
        <disable_local_modules>false</disable_local_modules>
        <resources>
            <db>
                <table_prefix><![CDATA[]]></table_prefix>
            </db>
            <default_setup>
                <connection>
                    <host><![CDATA[localhost]]></host>
                    <username><![CDATA[root]]></username>
                    <password><![CDATA[pass123]]></password>
                    <dbname><![CDATA[testdb]]></dbname>
                    <initStatements><![CDATA[SET NAMES utf8]]></initStatements>
                    <model><![CDATA[mysql4]]></model>
                    <type><![CDATA[pdo_mysql]]></type>
                    <pdoType><![CDATA[]]></pdoType>
                    <active>1</active>
                </connection>
            </default_setup>
        </resources>
        <session_save><![CDATA[files]]></session_save>
    </global>
    <admin>
        <routers>
            <adminhtml>
                <args>
                    <frontName><![CDATA[admin]]></frontName>
                </args>
            </adminhtml>
        </routers>
    </admin>
</config>
'

# exec issue
#exec 3<&- 3<<<"$xmlstr"
#exec 3<&- 3< <(printf '%s' "$xmlstr")
exec 3<&- 3<<EOF
$(printf '%s' "$xmlstr")
EOF

{ read -r host; read -r username; read -r password; read -r dbname; } < <(
       echo "cat /config/global/resources/default_setup/connection/*[self::host or self::username or self::password or self::dbname]/text()" | 
          xmllint --nocdata --shell /dev/fd/3 | 
          sed -e '1d;/d'
       )

printf '%s\n' "host: $host" "username: $username" "password: $password" "dbname: $dbname"

exec 3<&-
}
set -H


# output
# host: localhost
# username: root
# password: pass123
# dbname: testdb
2 of 9
14

Using xmllint and the --xpath option, it is very easy. You can simply do this:

XML_FILE=/path/to/file.xml

HOST=$(xmllint --xpath 'string(/config/global/resources/default_setup/connection/host)' $XML_FILE
USERNAME=$(xmllint --xpath 'string(/config/global/resources/default_setup/connection/username)' $XML_FILE
PASSWORD=$(xmllint --xpath 'string(/config/global/resources/default_setup/connection/password)' $XML_FILE 
DBNAME=$(xmllint --xpath 'string(/config/global/resources/default_setup/connection/dbname)' $XML_FILE

If you need to get to an element's attribute, that's also easy using XPath. Imagine you have the file:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<addon id="screensaver.turnoff"
       name="Turn Off"
       version="0.10.0"
       provider-name="Dag Wieërs">
  ..snip..
</addon>

The needed shell statements would be:

VERSION=$(xmllint --xpath 'string(/addon/@version)' $ADDON_XML)
AUTHOR=$(xmllint --xpath 'string(/addon/@provider-name)' $ADDON_XML)

You could try xmllint

The xmllint program parses one or more XML files, specified on the command line as xmlfile. It prints various types of output, depending upon the options selected. It is useful for detecting errors both in XML code and in the XML parser itse

It allows you select elements in the XML doc by xpath, using the --pattern option.

On Mac OS X (Yosemite), it is installed by default.
On Ubuntu, if it is not already installed, you can run apt-get install libxml2-utils

Answer from Joel on Stack Overflow
🌐
Baeldung
baeldung.com › home › files › file editing › xmllint in linux
xmllint in Linux | Baeldung on Linux
March 18, 2024 - Now, when we run the xmllint command ... </specification> ^ laptop-malformed.xml:6: parser error : EndTag: '</' not found ^ $ echo $? 1 ·...
🌐
Wikipedia
en.wikipedia.org › wiki › XMLStarlet
XMLStarlet - Wikipedia
September 8, 2025 - XMLStarlet is a set of command line utilities (toolkit) to query, transform, validate, and edit XML documents and files using a simple set of shell commands in a way similar to how it is done with UNIX grep, sed, awk, diff, patch, join, etc commands.
Find elsewhere
🌐
Ubuntu Manpages
manpages.ubuntu.com › manpages › focal › man1 › xmllint.1.html
Ubuntu Manpage: xmllint - command line XML tool
The xmllint program parses one or more XML files, specified on the command line as · XML-FILE (or the standard input if the filename provided is - ). It prints various types of output, depending upon the options selected. It is useful for detecting errors both in XML code and in the XML parser ...
🌐
Linux Hint
linuxhint.com › parse-xml-linux-command-line
How to Parse XML on Linux Command Line – Linux Hint
A guide on how to parse XML on the Linux Command Line by focusing on two options for parsing XML files, using the xmllint command and the XMLStarlet command.
🌐
Meld
gnome.pages.gitlab.gnome.org › libxml2 › xmllint.html
xmllint
The xmllint program parses one or more XML files, specified on the command line as XML-FILE (or the standard input if the filename provided is - ). It prints various types of output, depending upon the options selected. It is useful for detecting errors both in XML code and in the XML parser itself.
🌐
O'Reilly
oreilly.com › library › view › xml-hacks › 0596007116 › ch01s10.html
9. Test XML Documents from the Command Line - XML Hacks [Book]
July 27, 2004 - This hack discusses four tools: Richard Tobin’s RXP, Elcel’s XML Validator (xmlvalid), Daniel Veillard’s xmllint, and xmlwf (an application based on James Clark’s Expat C library). You’ve already seen the online version of RXP [Hack #8] . This hack shows you how to use the command-line version, available free at http://www.cogsci.ed.ac.uk/~richard/rxp.html.
Author   Michael Fitzgerald
Published   2004
Pages   479
🌐
GitHub
github.com › sibprogrammer › xq
GitHub - sibprogrammer/xq: Command-line XML and HTML beautifier and content extractor
Command-line XML and HTML beautifier and content extractor - sibprogrammer/xq
Starred by 1.1K users
Forked by 33 users
Languages   Go 92.6% | HTML 4.7% | Shell 2.2% | Dockerfile 0.5% | Go 92.6% | HTML 4.7% | Shell 2.2% | Dockerfile 0.5%
🌐
Reddit
reddit.com › r/askprogramming › command line xml parser/processor?
r/AskProgramming on Reddit: Command line XML parser/processor?
March 20, 2017 -

I've been using jq (https://stedolan.github.io/jq/) for a long time now to parse and reconstruct JSON from the commands line (Unix). It's a great tool for searching within JSON, extracting parts, constructing JSON, good stuff.

I'm usually doing stuff like curl http://server/endpoit.json | jq to get a pretty representation of the JSON response for example.

Lately I've been working for XML and I miss the power of jq.

What command lines tools do you use for XML parsing and filtering?

🌐
LiveJournal
kolya-iks.livejournal.com › 49403.html
bash xml parsing: kolya_iks — LiveJournal
xmllint — command line XML tool to parse xml files example of usage: 1.
🌐
Unix.com
unix.com › shell programming and scripting
Parsing XML using shell script - Shell Programming and Scripting - Unix Linux Community
October 19, 2017 - Well, issue is i have to parse this script to get the VERSION: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version…