提问人:helion3 提问时间:11/18/2010 最后编辑:Mateen Ulhaqhelion3 更新时间:10/14/2023 访问量:1719672
使用“find”时如何排除目录?
How do I exclude a directory when using `find`?
答:
使用主。例如,如果要排除:-prune
./misc
find . -path ./misc -prune -o -name '*.txt' -print
要排除多个目录,请将它们放在括号内。
find . -type d \( -path ./dir1 -o -path ./dir2 -o -path ./dir3 \) -prune -o -name '*.txt' -print
而且,要排除任何级别具有特定名称的目录,请使用 primary 而不是 .-name
-path
find . -type d -name node_modules -prune -o -name '*.json' -print
评论
./
./.git
find
find
-print
find . -type d \( -path "./Library/*" -o -path "./.Trash" \) -prune -o -name '.DS_Store' -print0 | xargs -0 rm
从我的 mac 上的 ~/ 很好地清理了它:)
-print
default
-false
-prune
find . -path ./misc -prune -false -o -name '*.txt' -print
find . -name '*.js' -\! -name 'glob-for-excluded-dir' -prune
评论
find ~/Projects -name '*.js' -\! -name 'node_modules' -prune
node_modules
find ~/Projects -path ~/Projects/node_modules -prune -o -name '*.js' -print
一种选择是排除所有包含带有 grep 的目录名称的结果。例如:
find . -name '*.js' | grep -v excludeddir
评论
-prune
find . -name '*.js' | grep -v excludeddir | grep -v excludedir2 | grep -v excludedir3
egrep -v '(dir1|dir2|dir3)'
find
使用 -prune 选项。所以,像这样:
find . -type d -name proc -prune -o -name '*.js'
'-type d -name proc -prune' 仅查找要排除的名为 proc 的目录。
“-o”是“OR”运算符。
评论
-print
find . -type d -name .hg -prune -o -name data
.hg
.hg
-print
/node_modules/
find . -name node_modules -prune -o -name '*.md'
我更喜欢符号......它更具可读性:-not
find . -name '*.js' -and -not -path directory
评论
find
find . -iname '*' -and -not -path './somePath'
不会阻止它进入所述目录。
find . -iname '*' -not -path './.git/*'
find . -not -path "*/.git*"
如果不适合您,这将:-prune
find -name "*.js" -not -path "./directory/*"
注意:需要遍历所有不需要的目录。
评论
-prune
.
*
find -name "*.js" -not -path "*/omitme/*"
-print
我发现以下内容比其他建议的解决方案更容易推理:
find build -not \( -path build/external -prune \) -name \*.js
# you can also exclude multiple paths
find build -not \( -path build/external -prune \) -not \( -path build/blog -prune \) -name \*.js
重要提示:您键入的路径必须与不排除的打印路径完全匹配。如果这句话让你感到困惑,只需确保在整个命令中使用完整的路径,如下所示:.如果您想更好地理解,请参阅注释 [1]。-path
find
find /full/path/ -not \( -path /full/path/exclude/this -prune \) ...
里面 和 是一个完全匹配的表达式(请参阅上面的重要说明),并且在成功时将避免遍历下面的任何内容。然后,将其分组为带有转义括号的单个表达式,并以该括号为前缀,将跳过与该表达式匹配的任何内容。\(
\)
build/external
-not
find
有人可能会问,添加是否会使隐藏的所有其他文件重新出现,答案是否定的。工作方式是,一旦访问该目录下的文件,任何内容都会被永久忽略。-not
-prune
-prune
这来自一个实际的用例,我需要对 wintersmith 生成的一些文件调用 yui-compressor,但省略了其他需要按原样发送的文件。
注意 [1]:如果要排除并运行 find like this “”,则必须指定 .另一方面,如果像这样运行查找,则必须指定 ./tmp/foo/bar
find /tmp \(...
-path /tmp/foo/bar
cd /tmp; find . \(...
-path ./foo/bar
评论
find . -not \( -path ./CVS -prune \) -type f -mtime +100 -delete find: The -delete action atomatically turns on -depth, but -prune does nothing when -depth is in effect. If you want to carry on anyway, just explicitly use the -depth option.
-exec rm -rf {} \;
-delete
find
.
-path
./
find -not \( -path ./.git -prune \) -type f
find searchdir \! \( -type d \( -path './excludedir/*' -o -path './excludedir2/*' -o -path './excludedir3/*' \) -prune \)
我用来提供 的文件列表,并想省略特定的目录及其内容。我尝试了许多组合组合,但无法完全排除我想要消失的目录。find
xgettext
-path
-prune
虽然我能够忽略我想要忽略的目录内容,然后返回目录本身作为结果之一,这导致崩溃(不接受目录;只接受文件)。find
xgettext
我的解决方案是简单地用于跳过结果中我不想要的目录:grep -v
find /project/directory -iname '*.php' -or -iname '*.phtml' | grep -iv '/some/directory' | xargs xgettext
无论是否有论据可以 100% 奏效,我都不能肯定地说。在一些头痛之后,使用是一个快速简便的解决方案。find
grep
之前的答案在 Ubuntu 上都不好。 试试这个:
find . ! -path "*/test/*" -type f -name "*.js" ! -name "*-min-*" ! -name "*console*"
我在这里找到了这个
评论
对于工作解决方案(在 Ubuntu 12.04 (Precise Pangolin) 上测试)...
find ! -path "dir1" -iname "*.mp3"
将在当前文件夹和子文件夹中搜索 MP3 文件,dir1 子文件夹除外。
用:
find ! -path "dir1" ! -path "dir2" -iname "*.mp3"
...排除 dir1 和 dir2
评论
要排除多个目录,请执行以下操作:
find . -name '*.js' -not \( -path "./dir1" -o -path "./dir2/*" \)
要添加目录,请添加:-o -path "./dirname/*"
find . -name '*.js' -not \( -path "./dir1" -o -path "./dir2/*" -o -path "./dir3/*"\)
但是,如果有许多目录要排除,也许您应该使用正则表达式。
对于跳过目录的首选语法应该是什么,这里显然存在一些混淆。
GNU意见
To ignore a directory and the files under it, use -prune
推理
-prune
停止下降到目录。仅指定仍将下降到跳过的目录,但每当测试每个文件时都会为 false。find
-not -path
-not -path
find
-prune
的问题
-prune
做了它想要做的事情,但仍然需要注意一些事情,在使用它时。
find
打印修剪后的目录。- 真这是预期的行为,它只是没有下降到它。若要避免完全打印目录,请使用逻辑上省略该目录的语法。
-prune
仅适用于-print
,而不能执行其他操作。- 不对。 适用于除 .为什么它不适用于删除?为了工作,find 需要按 DFS 顺序遍历目录,因为首先会删除叶子,然后是叶子的父项,依此类推......但是要指定才有意义,需要点击一个目录并停止下降它,这显然是没有意义的。
-prune
-delete
-delete
-delete
-prune
find
-depth
-delete
- 不对。 适用于除 .为什么它不适用于删除?为了工作,find 需要按 DFS 顺序遍历目录,因为首先会删除叶子,然后是叶子的父项,依此类推......但是要指定才有意义,需要点击一个目录并停止下降它,这显然是没有意义的。
性能
我对这个问题的三个最高投票答案设置了一个简单的测试(替换为显示另一个动作示例)。结果如下-print
-exec bash -c 'echo $0' {} \;
----------------------------------------------
# of files/dirs in level one directories
.performance_test/prune_me 702702
.performance_test/other 2
----------------------------------------------
> find ".performance_test" -path ".performance_test/prune_me" -prune -o -exec bash -c 'echo "$0"' {} \;
.performance_test
.performance_test/other
.performance_test/other/foo
[# of files] 3 [Runtime(ns)] 23513814
> find ".performance_test" -not \( -path ".performance_test/prune_me" -prune \) -exec bash -c 'echo "$0"' {} \;
.performance_test
.performance_test/other
.performance_test/other/foo
[# of files] 3 [Runtime(ns)] 10670141
> find ".performance_test" -not -path ".performance_test/prune_me*" -exec bash -c 'echo "$0"' {} \;
.performance_test
.performance_test/other
.performance_test/other/foo
[# of files] 3 [Runtime(ns)] 864843145
结论
f10bit 的语法和 Daniel C. Sobral 的语法平均需要 10-25 毫秒才能运行。GetFree 的语法(不使用 )花费了 865 毫秒。所以,是的,这是一个相当极端的例子,但如果你关心运行时间并且正在做任何远程密集型的事情,你应该使用 .-prune
-prune
注意:Daniel C. Sobral 的语法在两种 -prune
语法中表现更好;但是,我强烈怀疑这是某些缓存的结果,因为切换两者运行的顺序会导致相反的结果,而非修剪版本总是最慢的。
测试脚本
#!/bin/bash
dir='.performance_test'
setup() {
mkdir "$dir" || exit 1
mkdir -p "$dir/prune_me/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/w/x/y/z" \
"$dir/other"
find "$dir/prune_me" -depth -type d -exec mkdir '{}'/{A..Z} \;
find "$dir/prune_me" -type d -exec touch '{}'/{1..1000} \;
touch "$dir/other/foo"
}
cleanup() {
rm -rf "$dir"
}
stats() {
for file in "$dir"/*; do
if [[ -d "$file" ]]; then
count=$(find "$file" | wc -l)
printf "%-30s %-10s\n" "$file" "$count"
fi
done
}
name1() {
find "$dir" -path "$dir/prune_me" -prune -o -exec bash -c 'echo "$0"' {} \;
}
name2() {
find "$dir" -not \( -path "$dir/prune_me" -prune \) -exec bash -c 'echo "$0"' {} \;
}
name3() {
find "$dir" -not -path "$dir/prune_me*" -exec bash -c 'echo "$0"' {} \;
}
printf "Setting up test files...\n\n"
setup
echo "----------------------------------------------"
echo "# of files/dirs in level one directories"
stats | sort -k 2 -n -r
echo "----------------------------------------------"
printf "\nRunning performance test...\n\n"
echo \> find \""$dir"\" -path \""$dir/prune_me"\" -prune -o -exec bash -c \'echo \"\$0\"\' {} \\\;
name1
s=$(date +%s%N)
name1_num=$(name1 | wc -l)
e=$(date +%s%N)
name1_perf=$((e-s))
printf " [# of files] $name1_num [Runtime(ns)] $name1_perf\n\n"
echo \> find \""$dir"\" -not \\\( -path \""$dir/prune_me"\" -prune \\\) -exec bash -c \'echo \"\$0\"\' {} \\\;
name2
s=$(date +%s%N)
name2_num=$(name2 | wc -l)
e=$(date +%s%N)
name2_perf=$((e-s))
printf " [# of files] $name2_num [Runtime(ns)] $name2_perf\n\n"
echo \> find \""$dir"\" -not -path \""$dir/prune_me*"\" -exec bash -c \'echo \"\$0\"\' {} \\\;
name3
s=$(date +%s%N)
name3_num=$(name3 | wc -l)
e=$(date +%s%N)
name3_perf=$((e-s))
printf " [# of files] $name3_num [Runtime(ns)] $name3_perf\n\n"
echo "Cleaning up test files..."
cleanup
评论
-prune
name1() name2() name3()
date
time
find -name '*.js' -not -path './node_modules/*' -not -path './vendor/*'
似乎与
find -name '*.js' -not \( -path './node_modules/*' -o -path './vendor/*' \)
并且更容易记住 IMO。
how-to-use-prune-option-of-find-in-sh 是 Laurence Gonsalves 关于工作原理的一个很好的答案。-prune
这是通用解决方案:
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
为避免多次键入,请将 换成一对。/path/to/seach/
find
pushd .. popd
pushd /path/to/search; \
find . \
-type d \
\( -path ./exclude_me \
-o \
-name exclude_me_too_anywhere \
\) \
-prune \
-o \
-type f -name '*\.js' -print; \
popd
评论
-path
find . -path ./.git -prune -o -print
find $HOME/foo -path $HOME/foo/.git -prune -o -print
-path somedir
这适合我在 Mac 上:
find . -name *.php -or -path "./vendor" -prune -or -path "./app/cache" -prune
它将排除后缀为 的搜索名称的 和 dir。vendor
app/cache
php
评论
您可以使用修剪选项来实现此目的。例如:
find ./ -path ./beta/* -prune -o -iname example.com -print
或者反向 grep “grep -v” 选项:
find -iname example.com | grep -v beta
您可以在 Linux find 命令 从搜索中排除目录中找到详细说明和示例。
评论
find . -type f -print -o -path "*/node_modules" -prune
-print
-type f -print
find . -path "*/node_modules" -prune -o -type f -print
)
./node_modules
*/node_modules
node_modules
node_modules
find . -type f -print -o -path "./node_modules" -prune
node_modules
node_modules
./node_modules
node_modules
.
*/node_modules
*
./test5/main/node_modules
./
*
这是我用来排除某些路径的格式:
$ find ./ -type f -name "pattern" ! -path "excluded path" ! -path "excluded path"
我用它来查找不在“.*”路径中的所有文件:
$ find ./ -type f -name "*" ! -path "./.*" ! -path "./*/.*"
评论
-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 \)
对于那些使用旧版本的 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
评论
-prune
绝对有效,并且是最佳答案,因为它可以防止下降到要排除的目录。 它仍然搜索排除的目录,它只是不打印结果,如果排除的目录挂载了网络卷或您没有权限,这可能是一个问题。-not -path
棘手的部分是,它对参数的顺序非常讲究,所以如果你没有把它们弄得恰到好处,你的命令可能不起作用。参数的顺序通常如下:find
find {path} {options} {action}
{path}
:把所有与路径相关的参数放在第一位,比如. -path './dir1' -prune -o
{options}
:作为该组的最后一个选项,我最成功。例如-name, -iname, etc
-type f -iname '*.js'
{action}
:使用时需要添加-print
-prune
下面是一个工作示例:
# 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
评论
find / -type f -not \( -path "/proc" -prune \) -not \( -path "/proc/*" -prune \) -print | more
find / -not \( -path "/proc" -prune \) -not \( -path "/proc/*" -prune \) -type f -print | more
有很多好的答案,我只是花了一些时间来理解命令的每个元素的用途及其背后的逻辑。
find . -path ./misc -prune -o -name '*.txt' -print
find 将开始查找当前目录中的文件和目录,因此 .find .
该选项代表逻辑 OR,并将命令的两个部分分开:-o
[ -path ./misc -prune ] OR [ -name '*.txt' -print ]
任何不是 ./misc 目录的目录或文件都不会通过第一个测试。但它们将针对第二种表达式进行测试。如果它们的名称与图案相对应,则由于该选项,它们会被打印出来。-path ./misc
*.txt
-print
当 find 到达 ./misc 目录时,该目录仅满足第一个表达式。因此,该选项将应用于它。它告诉 find 命令不要浏览该目录。因此,./misc 中的任何文件或目录甚至不会被 find 探索,不会针对表达式的第二部分进行测试,也不会被打印出来。-prune
评论
这是唯一对我有用的。
find / -name MyFile ! -path '*/Directory/*'
搜索“MyFile”,不包括“Directory”。 强调星星 * .
评论
! -path '*/Directory/*'
docker container
sh -c "find..."
package.json
find . -name package.json ! -path '*/node_modules/*'
TLDR:了解您的根目录,并使用该选项从那里定制您的搜索。不要在排除的路径的末尾包含尾随。-path <excluded_path> -prune -o
/
例:
find / -path /mnt -prune -o -name "*libname-server-2.a*" -print
为了有效地使用 我认为必须充分了解您的文件系统目录结构。在我的家用计算机上,我有多TB的硬盘驱动器,其中大约一半的内容是使用(即)。虽然备份到物理上独立的(重复)驱动器,但它安装在我的系统根目录下:find
rsnapshot
rsync
/
/mnt/Backups/rsnapshot_backups/
/mnt/Backups/
└── rsnapshot_backups/
├── hourly.0/
├── hourly.1/
├── ...
├── daily.0/
├── daily.1/
├── ...
├── weekly.0/
├── weekly.1/
├── ...
├── monthly.0/
├── monthly.1/
└── ...
该目录目前占用 ~2.9 TB,有 ~60M 个文件和文件夹;简单地遍历这些内容需要时间:/mnt/Backups/rsnapshot_backups/
## As sudo (#), to avoid numerous "Permission denied" warnings:
time find /mnt/Backups/rsnapshot_backups | wc -l
60314138 ## 60.3M files, folders
34:07.30 ## 34 min
time du /mnt/Backups/rsnapshot_backups -d 0
3112240160 /mnt/Backups/rsnapshot_backups ## 3.1 TB
33:51.88 ## 34 min
time rsnapshot du ## << more accurate re: rsnapshot footprint
2.9T /mnt/Backups/rsnapshot_backups/hourly.0/
4.1G /mnt/Backups/rsnapshot_backups/hourly.1/
...
4.7G /mnt/Backups/rsnapshot_backups/weekly.3/
2.9T total ## 2.9 TB, per sudo rsnapshot du (more accurate)
2:34:54 ## 2 hr 35 min
因此,每当我需要在我的(根)分区上搜索文件时,我都需要处理(如果可能的话,避免)遍历我的备份分区。/
例子
在这个线程中建议的各种方法(如何在 find . 命令中排除目录),我发现使用接受的答案进行搜索要快得多——但需要注意。
解决方案 1
假设我想找到 系统文件 ,但我不想搜索我的备份。若要快速查找系统文件,请使用排除路径(即 use 、 not 、 或 ...):libname-server-2.a
rsnapshot
/mnt
/mnt
/mnt/
/mnt/Backups
## As sudo (#), to avoid numerous "Permission denied" warnings:
time find / -path /mnt -prune -o -name "*libname-server-2.a*" -print
/usr/lib/libname-server-2.a
real 0m8.644s ## 8.6 sec <<< NOTE!
user 0m1.669s
sys 0m2.466s
## As regular user (victoria); I also use an alternate timing mechanism, as
## here I am using 2>/dev/null to suppress "Permission denied" warnings:
$ START="$(date +"%s")" && find 2>/dev/null / -path /mnt -prune -o \
-name "*libname-server-2.a*" -print; END="$(date +"%s")"; \
TIME="$((END - START))"; printf 'find command took %s sec\n' "$TIME"
/usr/lib/libname-server-2.a
find command took 3 sec ## ~3 sec <<< NOTE!
...在几秒钟内找到该文件,而这需要更长的时间(似乎在所有“排除的”目录中递归):
## As sudo (#), to avoid numerous "Permission denied" warnings:
time find / -path /mnt/ -prune -o -name "*libname-server-2.a*" -print
find: warning: -path /mnt/ will not match anything because it ends with /.
/usr/lib/libname-server-2.a
real 33m10.658s ## 33 min 11 sec (~231-663x slower!)
user 1m43.142s
sys 2m22.666s
## As regular user (victoria); I also use an alternate timing mechanism, as
## here I am using 2>/dev/null to suppress "Permission denied" warnings:
$ START="$(date +"%s")" && find 2>/dev/null / -path /mnt/ -prune -o \
-name "*libname-server-2.a*" -print; END="$(date +"%s")"; \
TIME="$((END - START))"; printf 'find command took %s sec\n' "$TIME"
/usr/lib/libname-server-2.a
find command took 1775 sec ## 29.6 min
解决方案 2
此线程中提供的其他解决方案 (SO#4210042) 也表现不佳:
## As sudo (#), to avoid numerous "Permission denied" warnings:
time find / -name "*libname-server-2.a*" -not -path "/mnt"
/usr/lib/libname-server-2.a
real 33m37.911s ## 33 min 38 sec (~235x slower)
user 1m45.134s
sys 2m31.846s
time find / -name "*libname-server-2.a*" -not -path "/mnt/*"
/usr/lib/libname-server-2.a
real 33m11.208s ## 33 min 11 sec
user 1m22.185s
sys 2m29.962s
总结 |结论
使用“解决方案 1"
find / -path /mnt -prune -o -name "*libname-server-2.a*" -print
即
... -path <excluded_path> -prune -o ...
请注意,每当您将尾随添加到排除的路径时,该命令都会递归进入(所有这些)目录 - 在我的情况下,由于子目录,另外还包括 ~2.9 TB 的文件要搜索!通过不附加尾随,搜索应该几乎立即完成(在几秒钟内)。/
find
/mnt/*
/mnt/Backups/rsnapshot_backups/*
/
“解决方案 2”() 同样以递归方式搜索排除的目录 -- 不返回排除的匹配项,但不必要地消耗该搜索时间。... -not -path <exclude path> ...
在这些 rsnapshot
备份中搜索:
要在我的每小时/每天/每周/每月备份之一中查找文件:rsnapshot
$ START="$(date +"%s")" && find 2>/dev/null /mnt/Backups/rsnapshot_backups/daily.0 -name '*04t8ugijrlkj.jpg'; END="$(date +"%s")"; TIME="$((END - START))"; printf 'find command took %s sec\n' "$TIME"
/mnt/Backups/rsnapshot_backups/daily.0/snapshot_root/mnt/Vancouver/temp/04t8ugijrlkj.jpg
find command took 312 sec ## 5.2 minutes: despite apparent rsnapshot size
## (~4 GB), it is in fact searching through ~2.9 TB)
排除嵌套目录:
在这里,我想排除一个嵌套目录,例如 从以下位置搜索时:/mnt/Vancouver/projects/ie/claws/data/*
/mnt/Vancouver/projects/
$ time find . -iname '*test_file*'
./ie/claws/data/test_file
./ie/claws/test_file
0:01.97
$ time find . -path '*/data' -prune -o -iname '*test_file*' -print
./ie/claws/test_file
0:00.07
旁白:在命令末尾添加会禁止排除目录的打印输出:-print
$ find / -path /mnt -prune -o -name "*libname-server-2.a*"
/mnt
/usr/lib/libname-server-2.a
$ find / -path /mnt -prune -o -name "*libname-server-2.a*" -print
/usr/lib/libname-server-2.a
评论
find
sudo ls -R / | wc -l
/mnt/Vancouver/
ls -R | wc -l
/home/victoria/
避免打印修剪后的目录的一个好技巧是在 after 的右侧之后使用(也适用于)。例如。。。-print
-exec
-or
-prune
find . -path "*/.*" -prune -or -iname "*.j2"
将打印扩展名为“.j2”的当前目录下所有文件的路径,跳过所有隐藏目录。整洁。但它也会打印打印正在跳过的每个目录的完整路径,如上所述。但是,以下内容不会,...
find . -path "*/.*" -prune -or -iname "*.j2" -print
因为从逻辑上讲,在运算符之后和 -print 之前有一个隐藏的。由于布尔运算顺序和关联性,这会将其绑定到子句的右侧部分。但是文档说,如果它(或它的任何表亲......等)没有被指定,就会有一个隐藏的。那么为什么打印的左侧部分没有呢?显然(我从第一次阅读手册页开始就不明白这一点),如果没有 -或 ANYWHERE,这是真的,在这种情况下,-print 在逻辑上散布在周围,以便所有东西都被打印出来。如果在任何子句中表达了一个样式的操作,那么所有这些隐藏的逻辑操作都会消失,而你只得到你指定的内容。现在坦率地说,我可能更喜欢相反的方式,但是只有描述性运算符的 a 显然什么都不做,所以我想这是有道理的。如上所述,这也适用于,因此下面给出了具有所需扩展名的每个文件的完整列表,但没有列出每个隐藏目录的第一级,...-and
-iname
-or
-print
-print0
-or
-print
-exec
print
find
-exec
ls -la
find . -path "*/.*" -prune -or -iname "*.j2" -exec ls -la -- {} +
对于我(以及这个线程上的其他人)来说,语法很快就会变得非常巴洛克式,所以我总是加入 parens 以确保我知道什么绑定到什么,所以我通常会为类型能力创建一个宏,并形成所有这样的语句......find
find . \( \( ... description of stuff to avoid ... \) -prune \) -or \
\( ... description of stuff I want to find ... [ -exec or -print] \)
以这种方式将世界分为两部分很难出错。我希望这会有所帮助,尽管似乎不太可能有人读到第 30+个答案并投票,但人们可以希望。:-)
以下命令有效:
find . -path ./.git -prune -o -print
如果查找有问题,请使用该选项查看表达式分析信息。-D tree
find -D tree . -path ./.git -prune -o -print
或者 ,查看所有执行信息。-D all
find -D all . -path ./.git -prune -o -print
您还可以使用正则表达式来包含/排除某些文件/目录,使用如下所示:
find . -regextype posix-egrep -regex ".*\.(js|vue|s?css|php|html|json)$" -and -not -regex ".*/(node_modules|vendor)/.*"
这只会给你所有的js、vue、css等文件,但不包括和文件夹中的所有文件。node_modules
vendor
find . \( -path '.**/.git' -o -path '.**/.hg' \) -prune -o -name '*.js' -print
上面的示例查找当前目录下的所有文件,不包括文件夹和 ,无论这些文件和文件夹有多深。*.js
.git
.hg
.git
.hg
注意:这也有效:
find . \( -path '.*/.git' -o -path '.*/.hg' \) -prune -o -name '*.js' -print
但我更喜欢与其他一些工具保持一致的符号,这些工具在这里会偏离主题。**
如果有人正在研究如何一次忽略多个路径。 你可以使用 bash 数组(在 GNU bash 版本 4.4.20(1) -release 上完美工作)
#!/usr/bin/env bash
# This script helps ignore unnecessary dir paths while using the find command
EXCLUDE_DIRS=(
"! -path /*.git/*"
"! -path /*go/*"
"! -path /*.bundle/*"
"! -path /*.cache/*"
"! -path /*.local/*"
"! -path /*.themes/*"
"! -path /*.config/*"
"! -path /*.codeintel/*"
"! -path /*python2.7/*"
"! -path /*python3.6/*"
"! -path /*__pycache__/*"
)
find $HOME -type f ${EXCLUDE_DIRS[@]}
# if you like fzf
find $HOME -type f ${EXCLUDE_DIRS[@]} | fzf --height 40% --reverse
此外,由于某种原因,您将无法忽略 /bin/ 目录路径。
评论
-prune
__pycache__
/*__pycache__/*
./*__pycache__/*
find $HOME -type f $(< ~/excludelist)
! -path /*.git/*
! -path /*.mozilla/*
在 Linux Ubuntu 18.04、20.04 和 22.04 中测试。
find
它非常重要和强大,但它是如此微妙和令人困惑!
使用搜索文件时如何排除特定目录?
*.js
find
快速示例:排除所有具有给定前缀的目录
这是一个非常有用的例子,它没有直接回答OP的问题,但在我看来更有用:
@Kamil Dziedzic 在我的回答下方的评论中问道(针对语法和标点符号进行了更正):
如何忽略具有给定前缀的目录?例如,我想排除以
_
开头的目录。
方法如下:
# Ignore all directories (and their contents, via `-prune`) beginning with
# prefix "prefix" at the lowest level of the specified directory (`.`).
find . -not \( -path "./prefix*" -type d -prune \) | sort -V
# Ignore all directories (and their contents, via `-prune`) beginning with
# prefix "prefix" at any level recursively within the specified directory.
find . -not \( -path "*/prefix*" -type d -prune \) | sort -V
因此,对于 的目录前缀,请使用所需的任何一种:_
find . -not \( -path "./_*" -type d -prune \) | sort -V
find . -not \( -path "*/_*" -type d -prune \) | sort -V
解释:
.
表示“当前目录”*
是一个通配符,匹配任意数量的任意字符(如正则表达式find
.*
)\(
和转义括号。它们必须使用反斜杠进行转义,以便将它们作为参数传递给,而不是由 shell 解释器本身(例如 or 或您使用的任何 shell)进行处理\)
find
find
bash
sh
-not \( \)
表示忽略与括号内条件匹配的文件。-path "./prefix*"
表示匹配所有以 开头的路径,即位于命令中指定的目录最低级别的所有路径。 将匹配以 anything 开头的所有路径,后跟 ,表示搜索路径中任何目录中任何级别开头的任何路径。./prefix
.
find
-path "*/prefix*"
/prefix
prefix
-type d
说只匹配爱尔兰。这与刚刚指定的“和”一起“,使其仅匹配以您指定的前缀开头且类型为”directory“的文件。d
-path
-prune
表示不遍历到匹配的目录。From : “如果文件是一个目录,请不要下降到它。因此,如果没有该选项,目录本身将被排除在外,但该目录中的文件和文件不会被排除在外(甚至也不会被排除在外 - 也是因为它们不属于 )。添加可避免遍历到排除的目录,从而也排除该目录中的文件。这可能看起来很奇怪,但请记住,在 Linux 和 Unix 系统中,目录也是“文件”,只是特殊类型的文件,可以作为其他文件路径中的前缀。因此,考虑到这一点,必须使用更有意义。man find
-prune
./prefixWhateverDir
./prefixWhateverDir/file1.c
./prefixWhateverDir/file2.c
./prefixWhateverDir/prefixFile1.c
./prefixWhateverDir/prefixFile2.c
-type d
-prune
-prune
- 管道只是对输出进行排序,使其漂亮且按字母顺序排列。
sort -V
| sort -V
如果您认为 -not
或 -prune
是必需的,但不是两者,那是不正确的。请参阅我刚刚在下面添加的名为“处理其他注释”的新部分,以查看使用 -not 和 -prune、only -not
和 -prune
运行上述命令的详细示例。它们不是一回事。
OP问题的快速总结和回答:
这直接回答了OP的问题。
请遵循以下模式。另请参阅我的评论 这里.这些是我发现的最好和最有效的模式。转义括号 ( 和 ) 和选项对于速度非常重要。请阅读下文,了解原因。\(
\)
-prune
使用的最佳模式:
当然,如果您正在寻找一个通用答案而不是试图解决 OP 的原始问题,请删除下面每个命令的 -name '*
.js' 部分,这还涉及仅查找名称中扩展名为 .js
的文件。
# Exclude one path, and its contents, saving time by *not* recursing down the
# excluded path at all.
find . -name '*.js' -not \( -path "./dir_to_exclude" -prune \)
# Add the wildcard asterisk (`*`) to the end of the match pattern, as
# in "./dir_to_exclude*", to exclude all files & folders beginning with the
# name `./dir_to_exclude`. Prune to save time by *not* recursing down the
# excluded paths at all.
# - You can add the asterisk to the end of the pattern to apply this pattern to
# all examples below as well, if desired.
# - This example pattern would exclude "./dir_to_exclude", "./dir_to_exclude1",
# "./dir_to_exclude2", "./dir_to_exclude99", "./dir_to_exclude_some_long_name",
# "./dir_to_exclude_another_long_name", etc., as well as exclude all **files**
# beginning with this match pattern but not otherwise in an excluded dir.
find . -name '*.js' -not \( -path "./dir_to_exclude*" -prune \)
# Exclude multiple paths and their contents, saving time by *not* recursing down
# the excluded paths at all.
find . -name '*.js' \
-not \( -path "./dir_to_exclude1" -prune \) \
-not \( -path "./dir_to_exclude2" -prune \) \
-not \( -path "./dir_to_exclude3" -prune \)
# If you change your "starting point" path from `.` to something else, be sure
# to update the beginning of your `-path` with that as well, like this:
find "some_dir" -name '*.js' -not \( -path "some_dir/dir_to_exclude" -prune \)
find "some_dir" -name '*.js' \
-not \( -path "some_dir/dir_to_exclude1" -prune \) \
-not \( -path "some_dir/dir_to_exclude2" -prune \) \
-not \( -path "some_dir/dir_to_exclude3" -prune \)
上述模式是最好的,因为当该选项打开并带有转义括号时,如上所示,并且当您指定文件夹名称(在本例中不在文件夹名称后面),它同时排除文件夹及其内容。-prune
如果删除括号和选项,则不希望仅排除目录名称,而不排除其内容。如果您不遵循我上面推荐的模式,则必须仅排除文件夹名称,仅排除文件夹内容,并同时排除两者。-prune
-not -path "./dir_to_exclude"
-not -path "./dir_to_exclude"
-not -path "./dir_to_exclude/*"
-not -path "./dir_to_exclude" -not -path "./dir_to_exclude/*"
此外,从上面的示例中删除括号和选项需要 2 倍~100 倍的时间。这是一个巨大的速度差异!使用括号和选项会导致不递归排除的目录,但仍然会浪费大量时间递归排除的目录。-prune
-prune
find
find . -not -path "./dir_to_exclude" -not -path "./dir_to_exclude/*"
讨论细微差别和经验法则
使用时:find
您必须在尝试匹配的路径中包含通配符 () 或“起点”路径。例子:
*
-path
通过在前面加上 ur 以匹配 “starting point” 路径来匹配相对于 “starting point” 路径的精确路径:
-path
# 1. with the "starting point" being the current directory, `.` find . -not -path "./dir_to_exclude/*" # or (same thing) find -not -path "./dir_to_exclude/*" # 2. with the "starting point" being the root dir, `/` find / -not -path "/dir_to_exclude/*" # 3. with the "starting point" being "some_dir" find "some_dir" -not -path "some_dir/dir_to_exclude/*"
同样,请注意,在上述所有匹配项中,您必须以“起点”路径显式前缀路径。否则,您可以使用通配符:
-path
匹配通配符路径,以在搜索路径中的任何级别或子目录中查找您的路径。即:前缀 your with .例子:
-path
-path
*
# match "./dir_to_exclude/file1" as well as # "./another_dir/dir_to_exclude/file1" find . -not -path "*/dir_to_exclude/*" # match "/dir_to_exclude/file1" as well as # "/another_dir/dir_to_exclude/file1" find / -not -path "*/dir_to_exclude/*" # match "some_dir/dir_to_exclude/file1" as well as # "some_dir/another_dir/dir_to_exclude/file1" find "some_dir" -not -path "*/dir_to_exclude/*"
同样,请注意,在上面的所有匹配项中,我都用通配符字符显式地为路径加上前缀,以便在任何级别进行匹配。
-path
*
用于执行不区分大小写的路径匹配。从:
-ipath
man find
-ipath pattern Like -path. but the match is case insensitive.
例子:
# exclude "./dir_to_exclude/*", as well as "./DIR_TO_EXCLUDE/*", and # "./DiR_To_eXcluDe/*", etc. find . -not -ipath "./dir_to_exclude/*"
当不使用转义括号和选项时,仍将递归排除的路径,使其像泥巴一样慢。☹️
-prune
find
如果不使用转义括号和选项,则仅排除排除的目录的内容,而不排除排除的目录本身,并且仅排除目录名称本身,而不排除该目录中的内容(文件和文件夹)!同时使用两者来排除两者。例子:
-prune
find . -not -path "./dir_to_exclude/*"
find . -not -path "./dir_to_exclude"
# exclude the files and folders within the excluded dir, but # leaving "./dir_to_exclude" itself find . -not -path "./dir_to_exclude/*" # exclude the dir name only, but leaving (NOT excluding) all files and # folders within that dir! find . -not -path "./dir_to_exclude" # exclude both the folder itself, as well as its contents find . \ -not -path "./dir_to_exclude/*" \ -not -path "./dir_to_exclude"
本“经验法则”部分中的上述所有示例都是纯粹的垃圾和垃圾🧻 🗑 ☹️。我在开玩笑和夸大其词,但关键是:由于解释的原因,我认为它们远没有那么好。你应该用转义的括号和选项包装它们中的每一个,如下所示😀:
-prune
find . -not \( -path "./dir_to_exclude/*" -prune \) find -not \( -path "./dir_to_exclude/*" -prune \) find / -not \( -path "/dir_to_exclude/*" -prune \) find "some_dir" -not \( -path "some_dir/dir_to_exclude/*" -prune \) find . -not \( -path "*/dir_to_exclude/*" -prune \) find / -not \( -path "*/dir_to_exclude/*" -prune \) find "some_dir" -not \( -path "*/dir_to_exclude/*" -prune \) find . -not \( -ipath "./dir_to_exclude/*" -prune \) find . -not \( -path "./dir_to_exclude/*" -prune \) find . -not \( -path "./dir_to_exclude" -prune \) find . \ -not \( -path "./dir_to_exclude/*" -prune \) \ -not \( -path "./dir_to_exclude" -prune \)
这个选项真的很重要。这是它的意思,来自(强调后加):
-prune
man find
-prune
真;如果文件是目录,请不要下降到目录。如果给出,则没有效果。因为暗示,你不能有效地使用 和 一起使用。-depth
-prune
-delete
-depth
-prune
-delete
例如,跳过目录以及 它,并打印找到的其他文件的名称,执行如下操作:
src/emacs
find . -path ./src/emacs -prune -o -print
以上内容是我截至2022年9月4日的最新信息。下面的内容是我的旧答案,它仍然有大量有用的信息,但没有涵盖细微差别以及我上面介绍的内容。阅读它以获得更多知识并查看更多示例,将您上面学到的知识应用到我下面介绍的内容中。
一般示例
请注意,要排除的文件夹名称之前的 (或 ,见下文) 和要排除的文件夹名称之后的 (或 ,但请参阅下面的警告) 是必需的,以便排除 ,以及其中的任何内容!./
*/
/*
*
dir_to_exclude
此外,为了提高速度,并且不遍历排除的目录,请注意非常重要的转义分组括号和选项。前任:。-prune
find -not \( -path "*/dir_to_exclude/*" -prune \)
若要在手册页中查看这些转义分组括号的示例,请运行 ,然后按 进行搜索。例如,使用正则表达式模式搜索模式。按下 开始搜索手册页。搜索时按“下一场比赛”。man find
/\(
\\\(
EnterN
总结
这些工作:
# [my favorite #1] exclude contents of `dir_to_exclude` at the search root
find -not -path "./dir_to_exclude/*"
# exclude all files & folders beginning with the name `dir_to_exclude` at the
# search root
find -not -path "./dir_to_exclude*"
# [my favorite #2] exclude contents of `dir_to_exclude` at any level within your
# search path
find -not -path "*/dir_to_exclude/*"
# exclude all files & folders beginning with the name `dir_to_exclude` at any
# level within your search path
find -not -path "*/dir_to_exclude*"
# To exclude multiple matching patterns, use `-not -path "*/matching pattern/*"`
# multiple times, like this
find -not -path "*/dir_to_exclude1/*" -not -path "*/dir_to_exclude2/*"
[使用这些] 这些也有效,而且更好,因为它们不会不必要地沿着排除的路径遍历!:
(这在速度上有很大的不同(快 2x~100 倍)!请参阅此处和此处。您还可以在本地搜索字符串
\(
和 \) 的字符串 \( 和 \),
分别使用转义的搜索字符串 \\\( 和 \\\)
)。
find -not \( -path "./dir_to_exclude" -prune \) # works to exclude *both* the
# directory *and* its contents
# here, here but does *not*
# exclude the contents as well
# when the directory name is
# written like this in the
# examples above
find -not \( -path "./dir_to_exclude*" -prune \)
find -not \( -path "./dir_to_exclude/*" -prune \)
find -not \( -path "*/dir_to_exclude" -prune \) # same note as just above
find -not \( -path "*/dir_to_exclude*" -prune \)
find -not \( -path "*/dir_to_exclude/*" -prune \)
# To exclude multiple matching patterns at once, use the `-not \( ... \)`
# pattern multiple times, like this
find -not \( -path "*/dir_to_exclude1/*" -prune \) \
-not \( -path "*/dir_to_exclude2/*" -prune \)
...但这些不起作用:
# These do NOT work!
find -not -path "dir_to_exclude"
find -not -path "dir_to_exclude/*"
find -not -path "./dir_to_exclude"
find -not -path "./dir_to_exclude/"
关键是,一般来说,要使它起作用,你必须以 ./ 或 */ 开头每个匹配模式,并以 /
* 或 *
结束每个匹配模式,具体取决于你要实现的目标。我说“一般”,因为在上面的 -style 部分中有两个值得注意的例外。您可以通过它们右侧的注释来识别这两个例外,这些注释说:.-not \( ... \)
# works here but not above
进一步解释:
- [最好,取决于你想要什么]这行得通!排除您正在搜索的根目录下的所有文件和文件夹。请注意,这排除
了dir_to_exclude
中的所有子文件和子文件夹,但不排除dir_to_exclude
目录本身。dir_to_exclude
find -not \( -path "./dir_to_exclude/*" -prune \)
- 此外,请排除目录本身(以及名称以这些字符开头的任何文件或文件夹)。注意:这也不包括
dir_to_exclude1
、dir_to_exclude2
、dir_to_exclude_anyTextHere
等。它不包括仅以文本dir_to_exclude
开头且位于您正在搜索的根目录中的任何文件或文件夹。dir_to_exclude
find -not \( -path "./dir_to_exclude*" -prune \)
- [BEST,取决于您想要的内容]以递归方式排除搜索路径中任何级别的此名称的目录。只需在路径的前面添加一个通配符,而不是使用 用于指示搜索根目录。
*
.
find -not \( -path "*/dir_to_exclude/*" -prune \)
- 以递归方式排除名称以搜索路径中任何级别的字符开头的任何文件或文件夹。(另请参阅上面的警告)。
dir_to_exclude
find -not \( -path "*/dir_to_exclude*" -prune \)
总结:
在 中,开头的 表示“从当前目录开始”(或者在 中,是拾取到此时之前的任何字符的通配符),而在末尾,是通配符,用于拾取字符后面的路径字符串中的任何字符。这意味着以下几点:./
.
*/
*
/*
*
/
"./dir_to_exclude/*"
匹配根搜索目录 () 中的所有子文件和子文件夹,但与目录本身不匹配。dir_to_exclude
./
"./dir_to_exclude*"
匹配根搜索目录 () 中的所有文件和文件夹,包括 ,以及其中的所有内容,但也需要注意的是,它将匹配任何以字符开头的文件或文件夹名称。./
dir_to_exclude
dir_to_exclude
"*/dir_to_exclude/*"
匹配搜索路径 () 中任何级别的任何目录中的所有子文件和子文件夹,但与目录本身不匹配。dir_to_exclude
*/
"*/dir_to_exclude*"
匹配搜索路径中任何级别 (*/
) 的所有文件和文件夹,其名称以 开头。dir_to_exclude
走得更远
从那里,我喜欢通过管道在感兴趣的路径中搜索某些匹配模式。例如:搜索不在目录中的任何路径,并且其中有:grep
dir_to_exclude
desired_file_name.txt
# Case-sensitive; notice I use `\.` instead of `.` when grepping, in order to
# search for the literal period (`.`) instead of the regular expression
# wildcard char, which is also a period (`.`).
find -not \( -path "./dir_to_exclude/*" -prune \) \
| grep "desired_file_name\.txt"
# Case-INsensitive (use `-i` with your `grep` search)
find -not \( -path "./dir_to_exclude/*" -prune \) \
| grep -i "desired_file_name\.txt"
# To make `dir_to_exclude` also case INsensitive, use the `find` `-ipath` option
# instead of `-path`:
find -not -ipath \( -path "./dir_to_exclude/*" -prune \) \
| grep -i "desired_file_name\.txt"
要排除多个匹配模式,只需多次使用即可。前任:-not \( -path "*/matching pattern/*" -prune \)
# Exclude all ".git" and "..git" dirs at any level in your search path
find -not \( -path "*/.git/*" -prune \) -not \( -path "*/..git/*" -prune \)
我在这里使用上面的例子作为我的 sublf
别名的一部分(更新:该别名正在被扩展并移动到此处此文件夹中的脚本中)。这个别名允许我使用模糊查找器在 Sublime Text 中快速搜索和打开多个文件。有关它的最新版本,请参阅上面的链接。sublf.sh
fzf
alias sublf='FILES_SELECTED="$(find -not \( -path "*/.git/*" -prune \) \
-not \( -path "*/..git/*" -prune \) \
| fzf -m)" \
&& echo "Opening these files in Sublime Text:" \
&& echo "$FILES_SELECTED" \
&& subl $(echo "$FILES_SELECTED")'
处理其他意见
1.两者都需要得到预期的效果-prune
-not
来自@Ritin的评论(针对格式/措辞进行了修复):
@Gabriel订书钉,两者都不是必需的。使用或:
-not
-prune
-prune
-not
find . \( -path '*frontend*' -o -path '*/\.*' -o -path "*node_modules*" \) -prune -o -type f |sort -V
我的回应:
@Ritin,这是不正确的。为了获得我想要的效果,两者都是必需的。这正是我在回答开始时所说的:-not
-prune
find
它非常重要和强大,但它是如此微妙和令人困惑!
在我的 eRCaGuy_hello_world/cpp/ 文件夹中运行以下示例以查看差异:
两者兼而有之:
-not
-prune
命令和输出:
eRCaGuy_hello_world/cpp$ find . -not \( -path "./template*" -type d -prune \) | sort -V | grep -i '\./template' ./template_non_type_template_params_print_int_TODO.cpp
如您所见,此命令仅保留一个文件:.它剥离了所有以其路径开头的目录,以及其中的所有内容(文件和文件夹)。这就是我想要的效果。
./template_non_type_template_params_print_int_TODO.cpp
./template
-not
只:命令和输出:
eRCaGuy_hello_world/cpp$ find . -not \( -path "./template*" -type d \) | sort -V | grep -i '\./template' ./template_function_sized_array_param/print_array_calls_by_array_size.ods ./template_function_sized_array_param/readme.md ./template_function_sized_array_param/regular_func ./template_function_sized_array_param/regular_func.cpp ./template_function_sized_array_param/template_func ./template_function_sized_array_param/template_func.cpp ./template_non_type_template_params_print_int_TODO.cpp ./template_practice/explicit_template_specialization.cpp ./template_practice/research/Buckys C++ Programming Tutorials - 61 - Template Specializations - YouTube.desktop ./template_practice/research/Link to explicit (full) template specialization - cppreference.com%%%%%+.desktop ./template_practice/research/Link to template c++ - Google Search%%%%%.desktop ./template_practice/research/Link to template specialization - Google Search [videos]%%%%%.desktop ./template_practice/research/Link to template specialization - Google Search%%%%%.desktop ./template_practice/research/Template (C++) - Wikipedia.desktop ./template_practice/research/Template (C++) - Wikipedia.pdf ./template_practice/research/Template (C++) - Wikipedia_GS_edit.pdf ./template_practice/research/partial template specialization - cppreference.com.desktop ./template_practice/research/(7) Template Specialization In C++ - YouTube.desktop ./template_practice/run_explicit_template_specialization.sh
如您所见,此命令剥离了以 开头的两个文件夹,即: 和 。但是,它仍然递归到这些目录中,将所有内容(文件和文件夹)保留在这些目录中。和以前一样,该文件也存在。
./template
./template_function_sized_array_param
./template_practice
./template_non_type_template_params_print_int_TODO.cpp
-prune
只:命令和输出:
eRCaGuy_hello_world/cpp$ find . \( -path "./template*" -type d -prune \) | sort -V | grep -i '\./template' ./template_function_sized_array_param ./template_practice
如您所见,此命令仅查找 and 文件夹本身,但该选项表示不要递归到这些目录中,因此它不会在其中找到它们的内容(文件和文件夹)。它还错误地剥离了我不想要的文件。仅使用 -
prune
似乎与使用-not
only 完全相反。./template_function_sized_array_param
./template_practice
-prune
./template_non_type_template_params_print_int_TODO.cpp
同时使用两者会产生我想要的效果。-not
-prune
引用:
- [这个问题的主要答案]使用“find”时如何排除目录?
- https://unix.stackexchange.com/questions/350085/is-it-possible-to-exclude-a-directory-from-the-find-command/350172#350172
- https://unix.stackexchange.com/questions/32155/find-command-how-to-ignore-case/32158#32158
另请参阅:
- 我的回答:Unix 和 Linux:所有关于查找、过滤和排序的发现,基于文件大小
- [我仍然需要学习和阅读这个]https://www.baeldung.com/linux/find-exclude-paths
- [我的回答]如何将 find(文件的多行字符串列表)的输出存储到 bash 数组中
评论
查找
的 MacOs 手册显示并且都受支持,所以知道为什么它不起作用,或者如何让它在 Mac 上运行吗?-not
-path
tar
dir_to_exclude
find . -not \( -path "./_*" -type d -prune \) | sort -V
find . -not \( -path "*/_*" -type d -prune \) | sort -V
如果您正在寻找高性能的答案,那么它是:
find . -type d -name node_modules -prune -false -o -type f
用于排除node_modules本身。
-false
它将比在node_modules中有 10000 个文件的目录中的方法快 3 倍。-not -path
find . -type f -not -path '*node_modules*'
如果node_modules有更多的文件,您将获得更高的性能。
评论
*/.*
*/.vscode
find . \( -type d -name '.?*' ! -name '.vscode' \) -prune -false -o -name '*.json'
-prune
评论