使用find搜索*.js文件时,如何排除特定目录?
find . -name '*.js'
使用find搜索*.js文件时,如何排除特定目录?
find . -name '*.js'
当前回答
我在这个页面上找到了建议,很多其他页面在我的Mac OS X系统上都不起作用。然而,我发现了一种对我有用的变体。
大的想法是搜索Macintosh HD,但避免遍历所有外部卷,这些卷主要是Time Machine备份、映像备份、装载的共享和存档,但不必全部卸载,这通常是不切实际的。
这是我的工作脚本,我将其命名为“findit”。
#!/usr/bin/env bash
# inspired by http://stackoverflow.com/questions/4210042/exclude-directory-from-find-command Danile C. Sobral
# using special syntax to avoid traversing.
# However, logic is refactored because the Sobral version still traverses
# everything on my system
echo ============================
echo find - from cwd, omitting external volumes
date
echo Enter sudo password if requested
sudo find . -not \( \
-path ./Volumes/Archive -prune -o \
-path ./Volumes/Boot\ OS\ X -prune -o \
-path ./Volumes/C \
-path ./Volumes/Data -prune -o \
-path ./Volumes/jas -prune -o \
-path ./Volumes/Recovery\ HD -prune -o \
-path ./Volumes/Time\ Machine\ Backups -prune -o \
-path ./Volumes/SuperDuper\ Image -prune -o \
-path ./Volumes/userland -prune \
\) -name "$1" -print
date
echo ============================
iMac2:~ jas$
不同的路径与外部存档卷、Time Machine、虚拟机、其他装载的服务器等有关。一些卷名中有空格。
一个好的测试运行是“finditindex.php”,因为该文件出现在我的系统中的许多地方。使用此脚本,搜索主硬盘大约需要10分钟。如果没有这些例外,这需要很多小时。
其他回答
使用多模式-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
一个选项是使用grep排除包含目录名的所有结果。例如:
find . -name '*.js' | grep -v excludeddir
这是唯一一个对我有用的。
find / -name MyFile ! -path '*/Directory/*'
正在搜索“MyFile”,不包括“Directory”。强调星星*。
-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
使用-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