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

find . -name '*.js'

当前回答

使用-prune选项。因此,类似于:

find . -type d -name proc -prune -o -name '*.js'

“-typed-name-proc-prune”只查找要排除的名为proc的目录。“-o”是“OR”运算符。

其他回答

而不是:

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

…并且由于您没有定义要排除的子目录,因此可以使用:

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

此语法将排除所有子目录。

看看下面的示例:在tmp目录下,我有一个巨大的“归档”子目录,其中包含17000-4640=12360个文件。此目录位于慢速NFS上。虽然第一个语法扫描“archive”子目录并执行得很差,但第二个语法只扫描我当前目录中包含的“*pdf”文件并执行。。。没那么糟。

[tmp]$ time (find . -name "*pdf" | wc -l)
17000

real    0m40.479s
user    0m0.423s
sys     0m5.606s

[tmp]$ time (find *pdf -maxdepth 0 -name "*pdf" | wc -l)
4640

real    0m7.778s
user    0m0.113s
sys     0m1.136s

第二种语法非常有趣:在下面的示例中,我想检查文件or60runm50958.pdf是否存在,并且超过20分钟。亲自看看第二种语法是如何更有效的。这是因为它避免了扫描存档子目录。

[tmp]$ time find . -name or60runm50958.pdf -mmin +20
./or60runm50958.pdf

real    0m51.145s
user    0m0.529s
sys     0m6.243s

[tmp]$ time find or60runm50958.pdf -maxdepth 0 -name or60runm50958.pdf -mmin +20
or60runm50958.pdf

real    0m0.004s
user    0m0.000s
sys     0m0.002s

这是唯一一个对我有用的。

find / -name MyFile ! -path '*/Directory/*'

正在搜索“MyFile”,不包括“Directory”。强调星星*。

使用-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

使用多模式-o-name时的另一个示例

在根目录/中搜索所有*.tpl、*.tf文件,不包括位于/src/.traform/和/code/中的文件。

$ find / -type f \( -name '*.tf' -o -name '*.tpl' \) \
  -and \( -not -path '/src/.terraform/*' -and -not -path '/code/*' \)


/src/debug.tf
/src/nodegroup-infra.tpl
/src/variables.tf.tpl

我用hyperfine测试了上述命令;该测试是在具有3k个目录和12k个文件的系统上进行的。我认为可以公平地说,它足够快~70ms

Benchmark #1: ./entrypoint.sh
  Time (mean ± σ):      69.2 ms ±   1.4 ms    [User: 22.6 ms, System: 43.6 ms]
  Range (min … max):    66.4 ms …  72.2 ms    42 runs

目录结构示例

/代码/目录树

bash-5.0# tree /code
/code
├── debug.tf
├── entrypoint.sh
├── nodegroup-infra.tpl
├── tftemplate.sh
└── variables.tf.tpl

0 directories, 5 files

/src/目录树

bash-5.0# tree /src
/src
├── Dockerfile
├── debug.tf
├── entrypoint.sh
├── nodegroup-infra.tpl
├── terraform.tfstate
├── terraform.tfstate.backup
└── variables.tf.tpl

0 directories, 7 files

/根目录树摘要

$ tree /
...
3382 directories, 12164 files

对于那些在旧版本UNIX上无法使用-path或-not的用户

在SunOS 5.10 bash 3.2和SunOS 5.11 bash 4.4上测试

find . -type f -name "*" -o -type d -name "*excluded_directory*" -prune -type f