Creating a file based on output from a find -exec

I’m writing a shell script to batch validate (w3c validator) a load of HTML files.

I’m using which provides a python script to do the actual validation work.

The command I’m currently running is:

find . -type f -name "*q2*.html" -print -exec ~/Downloads/html5-lint-master/ -e {} ;

This is working and producing the output in the form:

The document is valid HTML5 + ARIA + SVG 1.1 + MathML 2.0 (subject to the utter previewness of this service).

When valid.

Or a list of errors – e.g.:

Error: Attribute “placeholder” is only allowed when the input type is “email”, “number”, “password”, “search”, “tel”, “text”, or “url”.
From line 53, column 13; to line 53, column 92
Error: Attribute “placeholder” is only allowed when the input type is “email”, “number”, “password”, “search”, “tel”, “text”, or “url”.
From line 57, column 13; to line 57, column 95
There were errors. (Tried in the text/html mode.)

Based on the response I’m hoping to create a file in the same folder as the HTML file called either valid.txt or invalid.txt containing the output.

Any tips on how best to achieve this?

Asked By: steve


You can use something like this:

find . -type f -name '*q2*.html' -execdir sh -c '
    your/script "$1" > invalid.txt
    grep -q "Error:" invalid.txt || mv invalid.txt valid.txt
' sh {} ;

Note that you will be overwriting the (in)valid.txt file if you have more than one html files matching your find, into the same directory. You would probably like to include $(basename "$1") into the output filename to make its name unique per directory.

With -execdir, the command is executed into the directory of every file found.

grep -q silently exits with failure (1) if no Error: found, so the command after || is executed. If error found, grep exits with success (0) and the mv is not executed.

You probably want to add some more for catching cases like some error of your script. Also ensure that the search pattern cannot exist for a valid file.

Another approach, independent of what messages your program is printing, is to use exit codes.

import sys to your python script and use sys.exit(0) for a valid file, or sys.exit(42) for an invalid one. After execution, you parse the exit code ($?) and decide what to do.

See also:


your/script "$1" > output.txt
((result == 0)) && do stuff for valid file
((result == 42)) && do stuff for invalid file
Answered By: thanasisp
Categories: Answers Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.