使用find搜索*.js文件时,如何排除特定目录?

find . -name '*.js'

当前回答

最好使用exec操作而不是for循环:

find . -path "./dirtoexclude" -prune \
    -o -exec java -jar config/yuicompressor-2.4.2.jar --type js '{}' -o '{}' \;

执行者…'{}' ... '{}' \; 将对每个匹配的文件执行一次,将大括号“{}”替换为当前文件名。

请注意,大括号括在单引号中,以防止它们被解释为shell脚本标点符号*。


笔记

*从find(GNU findutils)4.4.2手册页的EXAMPLES部分

其他回答

find . \( -path '.**/.git' -o -path '.**/.hg' \) -prune -o -name '*.js' -print

上面的示例查找当前目录下的所有*.js文件,不包括文件夹.git和.hg,无论这些.git和.h文件夹有多深。

注意:这也适用于:

find . \( -path '.*/.git' -o -path '.*/.hg' \) -prune -o -name '*.js' -print

但我更喜欢**表示法,以便与其他一些工具保持一致,这在这里可能会偏离主题。

path-prune方法还可以处理路径中的通配符。下面是一个find语句,它将查找服务于多个git存储库的git服务器的目录,而不包括git内部目录:

find . -type d \
   -not \( -path */objects -prune \) \
   -not \( -path */branches -prune \) \
   -not \( -path */refs -prune \) \
   -not \( -path */logs -prune \) \
   -not \( -path */.git -prune \) \
   -not \( -path */info -prune \) \
   -not \( -path */hooks -prune \)  

使用-prune主键。例如,如果要排除/其他:

find . -path ./misc -prune -o -name '*.txt' -print

要排除多个目录,请在括号中对它们进行“或”运算。

find . -type d \( -path ./dir1 -o -path ./dir2 -o -path ./dir3 \) -prune -o -name '*.txt' -print

而且,要在任何级别排除具有特定名称的目录,请使用-name primary而不是-path。

find . -type d -name node_modules -prune -o -name '*.json' -print

您可以使用修剪选项来实现这一点。例如:

find ./ -path ./beta/* -prune -o -iname example.com -print

或者反向grep“grep-v”选项:

find -iname example.com | grep -v beta

您可以在Linux find命令exclude directories from search中找到详细的说明和示例。

-prune绝对有效,并且是最好的答案,因为它可以防止下降到要排除的目录中-not-path仍然搜索排除的目录,它只是不打印结果,如果排除的目录已装入网络卷或您没有权限,这可能是一个问题。

棘手的是,find对参数的顺序非常讲究,所以如果你不能正确地获取它们,你的命令可能无法正常工作。论点的顺序一般如下:

find {path} {options} {action}

{path}:首先放置所有与路径相关的参数,如-路径'/dir1'-修剪-o

{options}:将-name、-iname等作为此组中的最后一个选项时,我最成功。例如-type f-iname“*.js”

{action}:使用-prine时需要添加-print

下面是一个工作示例:

# setup test
mkdir dir1 dir2 dir3
touch dir1/file.txt; touch dir1/file.js
touch dir2/file.txt; touch dir2/file.js
touch dir3/file.txt; touch dir3/file.js

# search for *.js, exclude dir1
find . -path './dir1' -prune -o -type f -iname '*.js' -print

# search for *.js, exclude dir1 and dir2
find . \( -path './dir1' -o -path './dir2' \) -prune -o -type f -iname '*.js' -print