You ask:
But how can I store the output to the same file for:
find . -name "*.py" -type f -exec grep "something" {} \
You misunderstand. The reason you can't pipe this to anything is that it is not a full command. The closing \
tells your shell to continue reading the command on the next line, which is not what you intend to do here. When you try:
find . -name "*.py" -type f -exec grep "something" {} \ > output.txt
the \
escapes a blank character that, as a result, will be passed as an extra argument to find
, and find
will complain that the command passed to its -exec
option isn't being terminated.
Terminating that command must be done by adding a +
or ;
token, and the ;
token is special to the shell, so it must be escaped or quoted. Additionally, {
and }
are also special in most shells, so they must be escaped or quoted as well:
find . -name "*.py" -type f -exec grep "something" \{} \;
or
find . -name "*.py" -type f -exec grep "something" '{}' ';'
These are valid commands, so you can redirect and pipe their output just fine:
find . -name "*.py" -type f -exec grep "something" \{} \; > output.txt
find . -name "*.py" -type f -exec grep "something" '{}' + | fgrep -v notthesefiles: > output.txt
By the way, I prefer to single-quote arguments if I don't want the shell to interpret any characters in them, even though (as @Kusalananda points out), that is not necessary in this case:
find . -name '*.py' -type f -exec grep 'something' \{} \; > output.txt
For the difference between ;
and +
, try man find
.