Don't loop over the output of find
. It's rather inelegant as the complete find
command has to finish and produce all its output before the loop can even run its first iteration. Furthermore you disqualify your script from working correctly with filenames that contain spaces. The result of the command substitution would be split on spaces to produce words for the loop to loop over.
Instead, let the find
command generate filenames for the loop like this:
find "$1" -type f -exec sh -c '...loop here...' sh {} +
We'll come back to this shortly.
The syntax on the line
if[ egrep 'it21754' $a ]
is a bit wonky, and you definitely do not need egrep
here (grep
is enough).
By "wonky" I mean that a [ ... ]
test usually looks like [ op arg ]
or [ arg op arg ]
where op
is some operator like -f
or -eq
or =
and arg
is a string. You use egrep
and it21754
and whatever $a
expands to, which is what generates the error that you get. You can't run egrep
in this context really, and you don't need to.
The correct if
-statement is
if grep -qwF 'it21754' "$a"; then
echo 0
else
echo 1
fi
The -qwF
flags makes grep
quiet (-q
), it makes it match using string comparisons rather than regular expressions (-F
), and it assures that the string matched will be a complete word rather than a substring (-w
). Here we use the exit status of grep
to choose whether to output a 0 (for a match) or 1 (for no match).
I've also double quoted $a
as "$a"
just in case the filename contains any spaces or filename globbing characters.
Interestingly enough, those are the numbers that grep
uses for its exit status anyway, so we could shorten the whole thing to just
grep -qwF 'it21754' "$a"
echo "$?"
The $?
variable holds the exit status of the most recently executed command.
Plugging that into our find
command, we get
find "$1" -type f -exec sh -c '
for a do
grep -qwF "it21754" "$a"
echo "$?"
done' sh {} +
This will produce a number of ones and zeroes depending on whether the files contain the given word or not. However, I think you may be looking for the filenames of the files that contain the word rather than a zero or a one. For that we may use
find "$1" -type f -exec grep -lwF 'it21754' {} +
Here, I've changed the -q
to a -l
("dash ell"). This calls grep
with the found files and grep
will only output the filenames of the ones that contains the given word. We don't need the sh -c
bit any longer since we're calling a single utility (not grep
and echo
).
Of course, you could do the same thing with just grep
:
grep -R -lwF 'it21754' "$1"
With -R
, grep
will search the subdirectories given on the command line recursively.
It may be worth noting that the -w
and -R
flags of grep
are not standard, but implemented by the most common grep
variants.
Related: