I often use the find
command to search through source code, delete files, whatever. Annoyingly, because Subversion stores duplicates of each file in its .
why not just
find . -not -iwholename '*.svn*'
The -not predicate negates everything that has .svn anywhere in the path.
So in your case it would be
find -not -iwholename '*.svn*' -name 'messages.*' -exec grep -Iw uint {} + \;
GNU find
find . ! -regex ".*[/]\.svn[/]?.*"
i usually pipe the output through grep one more time removing .svn, in my use it isn't much slower. typical example:
find -name 'messages.*' -exec grep -Iw uint {} + | grep -Ev '.svn|.git|.anythingElseIwannaIgnore'
OR
find . -type f -print0 | xargs -0 egrep messages. | grep -Ev '.svn|.git|.anythingElseIwannaIgnore'
Note that if you do
find . -type f -name 'messages.*'
then -print
is implied when the whole expression (-type f -name 'messages.*'
) is true, because there is no 'action' (like -exec
).
While, to stop descending into certain directories, you should use anything that matches those directories and follow it by -prune
(which is intended to stop descending into directories); like so:
find . -type d -name '.svn' -prune
This evaluates to True for the .svn directories, and we can use boolean short-circuit by following this by -o
(OR), after which what follows after the -o
is only checked when the first part is False, hence is not a .svn directory. In other words, the following:
find . -type d -name '.svn' -prune -o -name 'message.*' -exec grep -Iw uint {}
will only evalute what is right of the -o
, namely -name 'message.*' -exec grep -Iw uint {}
, for files NOT inside .svn directories.
Note that because .svn
is likely always a directory (and not for example a file), and in this case certainly isn't matching the name 'message.*', you might as well leave out the -type d
and do:
find . -name '.svn' -prune -o -name 'message.*' -exec grep -Iw uint {}
Finally, note that if you omit any action (-exec
is an action), say like so:
find . -name '.svn' -prune -o -name 'message.*'
then the -print
action is implied but will apply to the WHOLE expression, including the -name '.svn' -prune -o
part and thus print all .svn directories as well as the 'message.*' files, which is probably not what you want. Therefore you always should use an 'action' in the right-hand side of the boolean expression when using -prune
in this way. And when that action is printing you have to explicitly add it, like so:
find . -name '.svn' -prune -o -name 'message.*' -print
Try findrepo which is a simple wrapper around find/grep and much faster than ack You would use it in this case like:
findrepo uint 'messages.*'
To ignore .svn
, .git
and other hidden directories (starting with a dot), try:
find . -type f -not -path '*/\.*'
However, if the purpose of using find
is searching within the files, you may try to use these commands:
git grep
- specially designed command for searching patterns within the Git repository..gitignore
.Related: How do I find all files containing specific text on Linux?