Search code examples
bashgrepfindexecxargs

How to combine two commands in -exec parameter of find?


I have this find command to get all the files modified in the last 50 seconds which matchs with the following regex hell\d in the last 1000 characters. I use tail to get the last 1000 chars in order to speed up the search becouse the files to check are huge (3gb on average).

find /home/ouhma -newermt '50 seconds' -type f |
while read fic; do
    if tail -c 1000 "${fic}" | LANG=C LC_ALL=C grep -Pq 'hell\d'; then
        echo "${fic}"
    fi
done

It is posible to use -exec parameter to replace that ugly loop and to retrieve the result even faster?

This works, but I dont know if its the best way to do it:

find /home/ouhma -newermt '50 seconds' -type f -exec bash -c 'LANG=C LC_ALL=C grep -Pq "hell\d" <(tail -c 1000 "{}") && echo "{}"' \;

Solution

  • Multiple -exec actions can follow one another, one -exec will be run if the previous -exec succeeds i.e. the command run by -exec returns exit status 0.

    Do:

    find /home/ouhma -type f -newermt '50 seconds' -exec env LC_ALL=C \
           bash -c 'grep -Pq "hell\d" <(tail -c 1000 "$1")' _ {} \; -exec echo {} \;
    

    As you are just printing the filename, this would suffice though:

    find /home/ouhma -type f -newermt '50 seconds' -exec env LC_ALL=C \
           bash -c 'grep -Pq "hell\d" <(tail -c 1000 "$1") && echo "$1"' _ {} \;