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.
-name "die_xml_datei.xml"
; I don't know if this was something to fix.