How to ignore certain filenames using "find"?
You can use the negate (!) feature of find to not match files with specific names:
find . ! -name '*.html' ! -path '*.svn*' -exec grep 'SearchString' {} /dev/null \;
So if the name ends in .html or contains .svn anywhere in the path, it will not match, and so the exec will not be executed.
I've had the same issue for a long time, and there are several solutions which can be applicable in different situations:
ack-grep
is a sort of "developer'sgrep
" which by default skips version control directories and temporary files. Theman
page explains how to search only specific file types and how to define your own.grep
's own--exclude
and--exclude-dir
options can be used very easily to skip file globs and single directories (no globbing for directories, unfortunately).find . \( -type d -name '.svn' -o -type f -name '*.html' \) -prune -o -print0 | xargs -0 grep ...
should work, but the above options are probably less of a hassle in the long run.
The following find
command does prune directories whose names contain .svn
, Although it does not descend into the directory, the pruned path name is printed ...(-name '*.svn'
is the cause!) ..
You can filter out the directory names via: grep -d skip
which silently skips such input "directory names".
With GNU grep, you can use -H
instead of /dev/null
.
As a slight side issue: \+
can be much faster than \;
, eg. for 1 million one-line files, using \;
it took 4m20s, using \+
it took only 1.2s.
The following method uses xargs
instead of -exec
, and assumes there are no newlines \n
in any of your file names. As used here, xargs
is much the same as find's \+
.
xargs
can pass file-names which contain consecutive spaces by changing the input delimiter to '\n'
with the -d
option.
This excludes directories whose names contain .svn
and greps only files which don't end with .html
.
find . \( -name '*.svn*' -prune -o ! -name '*.html' \) |
xargs -d '\n' grep -Hd skip 'SearchString'