TLDR:使用-path <excluded_path> -prune -o
选项了解您的根目录并从那里定制搜索。不要/
在排除路径的末尾添加尾随。
例:
find / -path /mnt -prune -o -name "*libname-server-2.a*" -print
为了有效地使用find
I,我相信对文件系统目录结构有一个很好的了解。在我的家用计算机上,我具有多TB硬盘驱动器,其中大约一半的内容是使用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/
└── ...
该/mnt/Backups/rsnapshot_backups/
目录当前占用约2.9 TB的空间,其中包含约6000万个文件和文件夹。仅仅遍历这些内容需要花费时间:
## 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
假设我要查找系统文件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 ...
请注意,无论何时将尾随添加/
到排除的路径中,该find
命令都会递归地进入(所有这些)/mnt/*
目录-在我的情况下,由于/mnt/Backups/rsnapshot_backups/*
子目录的原因,该目录还包括约2.9 TB的文件搜索!通过不添加结尾/
,搜索应几乎立即完成(几秒钟内)。
... -not -path <exclude path> ...
同样,“解决方案2”()似乎可以在被排除的目录中进行递归搜索-不返回被排除的匹配项,但不必要地浪费了搜索时间。
在那些内搜索 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