20

I have a find looking like this:

rm -f crush-all.js
find . -type f \( -name "*.js" ! -name "*-min*" ! -name "*console*" \) | while read line
do
   cat "$line" >> crush-all.js
   echo >> crush-all.js
done

I'd like to add to exclude a directory called "test" in the find but I can't seem to figure out how to add "-type d" somehow. How'd I go about doing that?

Thanks!

5 Answers 5

26

You can use the -path option to find and combine it with the -not operator.

find . ! -path "*/test/*" -type f -name "*.js" ! -name "*-min-*" ! -name "*console*"

Please note two things

  • -path must come as the first argument
  • the pattern matches the whole filename, so -path test will not match anything, ever

By the way, I'm not sure why you are using parentheses, it doesn't make a difference. It is only used for precedence, for constructs such as ! \( -name '*bla*' -name '*foo*' \) (that is, do not find things that have both bla and foo).

A further refinement: no need to use the bash loop, you can simply do

find . ... -exec cat {} \; -exec echo \;

where ... are the other arguments to find.

4
find / -path ./test -prune -o ...

Rename ./test to fit the location of you test directory.

1
  • 2
    In this case, do not forget add -print action (because -print is not default action) after -o option
    – Bill Zhao
    Jun 23, 2016 at 4:48
2

To expand on what I think @CharlesClavadetscher was going for with his answer. If you omit a path with -not -path ... find will continue descending the path. Instead, using -prune will stop it from descending further into the omitted path, making it faster. So you can do something like

find . -path '*test/*' -prune -o -type f -name "*.js" ! -name "*-min*" ! -name "*console*" -print
1

You can try with grep like this (the folder here is named test_folder):

find . -type f \( -name "*.js" ! -name "*-min*" ! -name "*console*" \) | grep -v "/path/to/test_folder/" | while read line

or if your find returns relative path :

find . -type f \( -name "*.js" ! -name "*-min*" ! -name "*console*" \) | grep -v "./relative_path/to/test_folder/" | while read line

or if you want all folders that has the same name but with different path

find . -type f \( -name "*.js" ! -name "*-min*" ! -name "*console*" \) | grep -v "/test_folder/" | while read line

Best regards,

0

I use "not wholename" when I'm just searching for a file. -name tests the actual filename, but -wholename tests the full path. So adding an ignore for test to the question above:

find . -type f \( -name "*.js" ! -name "*-min*" ! -name "*console*" \) ! -wholename "*test*"

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .