egrep -vl '*.pdf' some_file
examines the file content, not name.
The right way to exclude names with find
is to negate (!
) a proper -name
(or -iname
if available) expression. Example:
find . -maxdepth 1 ! -name '*.pdf' -exec grep -l abc {} \;
Each result was printed twice because after the first grep
printed it and returned success, the second one (egrep
) apparently didn't find *.pdf
(interpreted as an extended regular expression) in the respective file content and thus (mind the -v
) printed the same name.
Note -exec
is also a test. In your case if the first -exec
reports failure then the second -exec
will not be triggered. The first -exec
will report failure if its grep
reports failure. And the grep
will report failure if it doesn't find the pattern in the file. This means any file that is not printed by the first grep
cannot be printed by the second one (egrep
) because the second one doesn't even run for the file.
Another way to exclude .pdf
files is to filter the output of your first find
(which in your case is in fact the output of grep
s; your find
prints nothing by itself). Like this:
find . -maxdepth 1 -exec grep -l abc {} \; | grep -iv '\.pdf$'
But if any path returned by find
is multi-line (i.e. if it includes newlines; filenames in Linux can) then the added grep
will perceive each line separately anyway, as if the lines referred to more than one file; and you will get unexpected results. Therefore testing inside find
(-name …
) is better.