How to exclude a directory in find . command

2018-12-31 09:21发布

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.

for file in $(find . -name '*.js')
do 
  java -jar config/yuicompressor-2.4.2.jar --type js $file -o $file
done

标签: linux shell find
30条回答
不流泪的眼
2楼-- · 2018-12-31 10:02

For what I needed it worked like this, finding landscape.jpg in all server starting from root and excluding the search in /var directory:

find / -maxdepth 1 -type d | grep -v /var | xargs -I '{}' find '{}' -name landscape.jpg

find / -maxdepth 1 -type d lists all directories in /

grep -v /var excludes `/var' from the list

xargs -I '{}' find '{}' -name landscape.jpg execute any command, like find with each directory/result from list

查看更多
琉璃瓶的回忆
3楼-- · 2018-12-31 10:04

I find the following easier to reason about than other proposed solutions:

find build -not \( -path build/external -prune \) -name \*.js

This comes from an actual use case, where I needed to call yui-compressor on some files generated by wintersmith, but leave out other files that need to be sent as-is.

Inside \( and \) is an expression that will match exactly build/external (it will not match if you did find ./build, for example -- you need to change it to ./build/external in that case), and will, on success, avoid traversing anything below. This is then grouped as a single expression with the escaped parenthesis, and prefixed with -not which will make find skip anything that was matched by that expression.

One might ask if adding -not will not make all other files hidden by -prune reappear, and the answer is no. The way -prune works is that anything that, once it is reached, the files below that directory are permanently ignored.

That is also easy to expand to add additional exclusions. For example:

find build -not \( -path build/external -prune \) -not \( -path build/blog -prune \) -name \*.js
查看更多
宁负流年不负卿
4楼-- · 2018-12-31 10:05

I was using find to provide a list of files for xgettext, and wanted to omit a specific directory and its contents. I tried many permutations of -path combined with -prune but was unable to fully exclude the directory which I wanted gone.

Although I was able to ignore the contents of the directory which I wanted ignored, find then returned the directory itself as one of the results, which caused xgettext to crash as a result (doesn't accept directories; only files).

My solution was to simply use grep -v to skip the directory that I didn't want in the results:

find /project/directory -iname '*.php' -or -iname '*.phtml' | grep -iv '/some/directory' | xargs xgettext

Whether or not there is an argument for find that will work 100%, I cannot say for certain. Using grep was a quick and easy solution after some headache.

查看更多
时光乱了年华
5楼-- · 2018-12-31 10:05

I tried command above, but none of those using "-prune" works for me. Eventually I tried this out with command below:

find . \( -name "*" \) -prune -a ! -name "directory"
查看更多
临风纵饮
6楼-- · 2018-12-31 10:06

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.

查看更多
零度萤火
7楼-- · 2018-12-31 10:07

how-to-use-prune-option-of-find-in-sh is an excellent answer by Laurence Gonsalves on how -prune works.

And here is the generic solution:

find /path/to/search                    \
  -type d                               \
    \( -path /path/to/search/exclude_me \
       -o                               \
       -name exclude_me_too_anywhere    \
     \)                                 \
    -prune                              \
  -o                                    \
  -type f -name '*\.js' -print

To avoid typing /path/to/seach/ multiple times, wrap the find in a pushd .. popd pair.

pushd /path/to/search;                  \
find .                                  \
  -type d                               \
    \( -path ./exclude_me               \
       -o                               \
       -name exclude_me_too_anywhere    \
     \)                                 \
    -prune                              \
  -o                                    \
  -type f -name '*\.js' -print;         \
 popd
查看更多
登录 后发表回答