I\'m trying to run a find
command for all JavaScript files, but how do I exclude a specific directory?
Here is the find
code we\'re using.<
find . -name '*.js' -\! -name 'glob-for-excluded-dir' -prune
The following commands works:
find . -path ./.git -prune -o -print
If You have a problem with find, use the -D tree
option to view the expression analysis information.
find -D tree . -path ./.git -prune -o -print
Or the -D all
, to see all the execution information.
find -D all . -path ./.git -prune -o -print
Use the -prune option. So, something like:
find . -type d -name proc -prune -o -name '*.js'
The '-type d -name proc -prune' only look for directories named proc to exclude.
The '-o' is an 'OR' operator.
a good trick for avoiding printing the pruned directories is to use -print
(works for -exec
as well) after the right side of the -or
after -prune
. For example, ...
find . -path "*/.*" -prune -or -iname "*.j2"
will print the path of all files beneath the current directory with the `.j2" extension, skipping all hidden directories. Neat. But it will also print the print the full path of each directory one is skipping, as noted above. However, the following does not, ...
find . -path "*/.*" -prune -or -iname "*.j2" -print
because logically there's a hidden -and
after the -iname
operator and before the -print. This binds it to the right part of the -or
clause due to boolean order of operations and associativity. But the docs say there's a hidden -print
if it (or any of its cousins ... -print0
, etc) is not specified. So why isn't the left part of the -or
printing? Apparently (and I didn't understand this from my first reading the man page), that is true if there there is no -print
-or -exec
ANYWHERE, in which case, -print is logically sprinkled around such that everything gets printed. If even ONE print
-style operation is expressed in any clause, all those hidden logical ones go away and you get only what you specify. Now frankly, I might have preferred it the other way around, but then a find
with only descriptive operators would apparently do nothing, so I guess it makes sense as it is. As mentioned above, this all works with -exec
as well, so the following gives a full ls -la
listing for each file with the desired extension, but not listing the first level of each hidden directory, ...
find . -path "*/.*" -prune -or -iname "*.j2" -exec ls -la -- {} +
For me (and others on this thread), find
syntax gets pretty baroque pretty quickly, so I always throw in parens to make SURE I know what binds to what, so I usually create a macro for type-ability and form all such statements as ...
find . \( \( ... description of stuff to avoid ... \) -prune \) -or \
\( ... description of stuff I want to find ... [ -exec or -print] \)
It's hard to go wrong by setting up the world into two parts this way. I hope this helps, though it seems unlikely for anyone to read down to the 30+th answer and vote it up, but one can hope. :-)
This is the format I used to exclude some paths:
$ find ./ -type f -name "pattern" ! -path "excluded path" ! -path "excluded path"
I used this to find all files not in ".*" paths:
$ find ./ -type f -name "*" ! -path "./.*" ! -path "./*/.*"
For a working solution (tested on Ubuntu 12.04 (Precise Pangolin))...
find ! -path "dir1" -iname "*.mp3"
will search for MP3 files in the current folder and subfolders except in dir1 subfolder.
Use:
find ! -path "dir1" ! -path "dir2" -iname "*.mp3"
...to exclude dir1 AND dir2