Find Command – How to Pipe Commands Inside find -exec

findpipeshell

Let's suppose I want to find all .txt files and search for some string. I would do:

find ./ -type f -name "*.txt" -exec egrep -iH 'something' '{}' \;

What if I want to do a more complex filtering, like this:

egrep something file.txt | egrep somethingelse | egrep other

Inside find -exec? (or similar)

Please keep in mind that I'm searching for a solution that I could easily type when I need it. I know that this could be done with a few lines using a shell script, but that isn't what I'm looking for.

Best Answer

If you must do it from within find, you need to call a shell:

find ./ -type f -name "*.txt" -exec sh -c 'grep -EiH something "$1" | grep -E somethingelse | grep -E other' sh {} \;

Other alternatives include using xargs instead:

find ./ -type f -name "*.txt" | 
    xargs -I{} grep -EiH something {} | 
        grep -EiH somethingelse | 
            grep -EiH other

Or, much safer for arbitrary filenames (assuming your find supports -print0):

find ./ -type f -name "*.txt" -print0 | 
    xargs -0 grep -EiH something {} | 
        grep -Ei somethingelse | 
            grep -Ei other

Or, you could just use a shell loop instead:

find ./ -type f -name "*.txt" -print0 | 
    while IFS= read -d '' file; do 
        grep -Ei something "$file" | 
            grep -Ei somethingelse | 
                grep -Ei other
    done
Related Question