0

With xmllint I check all XML files in the folder and if xmllint finds an invalid XML file there is an output.

My question: how can I write this output to a log file?

I found this command on the Internet:

find -type f -name "die_xml_datei.xml" -exec xmllint --noout {} \;

Here are my attempts:

find -type f -name "die_xml_datei.xml" -exec xmllint --output xml_not_valide.txt 2>&1
find -type f -name "die_xml_datei.xml" -exec xmllint --output xml_not_valide.txt {} \;
find -type f -name "die_xml_datei.xml" -exec xmllint --output > xml_not_valide.txt {} \;
1
  • I answered and did my best. Next time please provide more information: where does each attempt fail? what exactly in its output is wrong? E.g. you mentioned "all XML files" but used -name "die_xml_datei.xml"; I don't know if this was something to fix. Commented May 4, 2020 at 14:29

1 Answer 1

0

The output you're after is printed to stdout. Each xmllint will inherit the stdout from find, so the simplest approach is just to redirect the stdout of find:

find -type f -name "*.xml" -exec xmllint --noout {} \; 2>xml_not_valide.txt

However if find prints anything to stdout then it will be written to the file as well.

A single xmllint can take more than one file to check. Reduce the number of new processes by running xmllint for as many arguments as possible:

find -type f -name "*.xml" -exec xmllint --noout {} + 2>xml_not_valide.txt

If you want to redirect stderr from xmllint process(es) but not from find then you need to run an additional shell:

: >xml_not_valide.txt
find -type f -name "*.xml" -exec sh -c '
   xmllint --noout "$@" 2>>xml_not_valide.txt
' find-sh {} +

Note I used >> because find -exec sh … + does not guarantee there will be only one sh. Note each redirection with > truncates the file. We want to truncate once at the very beginning, so we redirect the output of null command :; after this >> is the way to go.


If you need to know problematic files without the detailed output of xmllint, make use of its exit status. The tool will return non-zero if there are problems, zero otherwise. Use -exec … \; as a (negated) test:

find -type f -name "*.xml" ! -exec xmllint --noout {} \; -print 2>/dev/null >xml_not_valide.txt

Only if ! -exec … succeeds (e.i. if -exec … fails, i.e. if xmllint returns non-zero), find will -print. It will print to stdout. We silence what xmllint prints to stderr and keep what find prints to its stdout.

You cannot do this with -exec … +. This time you must run one xmllint per file.

1
  • Hi, thanks for your help, I'm using: find -type f -name "*.xml" -exec xmllint --noout {} \; 2> xml_not_valide.txt works very well.
    – webuser57
    Commented May 6, 2020 at 12:23

You must log in to answer this question.

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