pipe commands inside find -exec?

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

Edit: This answer is not preferred, but is left here for comparison and illustration of potentially dangerous pitfalls in bash scripting.


You can put bash (or another shell) as your -exec command:

find -type -f -name "*.txt" -exec bash -c 'egrep -iH something "{}" | egrep somethingelse | egrep other' \;

One of the downsides of doing it this way is that it creates more potential for nested quoting issues as your commands get more complex. If you want to avoid that, you can break it out into a for-loop:

for i in $(find -type -f -name "*.txt"); do
  if egrep -iH something "$i" | egrep somethingelse | egrep other; then 
    echo "Found something: $i"
  fi
done

Tags:

Shell

Pipe

Find