TLDR: hiểu các thư mục gốc của bạn và điều chỉnh tìm kiếm của bạn từ đó, bằng cách sử dụng -path <excluded_path> -prune -o
tùy chọn. Không bao gồm một dấu /
ở cuối con đường bị loại trừ.
Thí dụ:
find / -path /mnt -prune -o -name "*libname-server-2.a*" -print
Để sử dụng hiệu quả, find
tôi tin rằng bắt buộc phải hiểu rõ về cấu trúc thư mục hệ thống tệp của bạn. Trên máy tính ở nhà của tôi, tôi có ổ cứng nhiều TB, với khoảng một nửa nội dung được sao lưu bằng cách sử dụng rsnapshot
(nghĩa là rsync
). Mặc dù sao lưu vào ổ đĩa độc lập (trùng lặp) vật lý, nó được gắn trong thư mục root ( /
) của hệ thống của tôi /mnt/Backups/rsnapshot_backups/
::
/mnt/Backups/
└── rsnapshot_backups/
├── hourly.0/
├── hourly.1/
├── ...
├── daily.0/
├── daily.1/
├── ...
├── weekly.0/
├── weekly.1/
├── ...
├── monthly.0/
├── monthly.1/
└── ...
Thư mục /mnt/Backups/rsnapshot_backups/
hiện chiếm ~ 2,9 TB, với ~ 60M tệp và thư mục; chỉ đơn giản là đi qua những nội dung đó cần có thời gian:
## 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
Vì vậy, bất cứ khi nào tôi cần tìm kiếm một tệp trên /
phân vùng (root) của mình, tôi cần phải xử lý (tránh nếu có thể) đi qua phân vùng sao lưu của tôi.
VÍ DỤ
Trong số các cách tiếp cận được đề xuất khác nhau trong chủ đề này ( Cách loại trừ một thư mục trong lệnh find. ), Tôi thấy rằng các tìm kiếm sử dụng câu trả lời được chấp nhận là rất nhiều nhanh hơn - với sự cẩn thận.
Giải pháp 1
Giả sử tôi muốn tìm tệp hệ thống libname-server-2.a
, nhưng tôi không muốn tìm kiếm thông qua các rsnapshot
bản sao lưu của mình . Để nhanh chóng tìm thấy tệp hệ thống, hãy sử dụng đường dẫn loại trừ /mnt
(nghĩa là sử dụng /mnt
, không /mnt/
, hoặc /mnt/Backups
, hoặc ...):
## 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!
... Tìm thấy tệp đó chỉ trong vài giây, trong khi quá trình này mất nhiều thời gian hơn (dường như được lặp lại qua tất cả các thư mục "bị loại trừ"):
## 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
Giải pháp 2
Giải pháp khác được cung cấp trong chuỗi này ( SO # 4210042 ) cũng hoạt động kém:
## 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
TÓM TẮT | KẾT LUẬN
Sử dụng phương pháp minh họa trong " Giải pháp 1 "
find / -path /mnt -prune -o -name "*libname-server-2.a*" -print
I E
... -path <excluded_path> -prune -o ...
lưu ý rằng bất cứ khi nào bạn thêm dấu vết /
vào đường dẫn bị loại trừ, find
lệnh sẽ truy xuất đệ quy (tất cả các /mnt/*
thư mục ) - trong trường hợp của tôi, vì các /mnt/Backups/rsnapshot_backups/*
thư mục con, ngoài ra còn bao gồm ~ 2,9 TB tệp để tìm kiếm! Bằng cách không nối thêm một dấu /
, tìm kiếm sẽ hoàn thành gần như ngay lập tức (trong vài giây).
"Giải pháp 2" ( ... -not -path <exclude path> ...
) tương tự xuất hiện để tìm kiếm đệ quy thông qua các thư mục bị loại trừ - không trả về kết quả khớp bị loại trừ, nhưng không cần thiết phải tiêu tốn thời gian tìm kiếm đó.
Tìm kiếm trong những rsnapshot
bản sao lưu đó:
Để tìm một tệp trong một rsnapshot
bản sao lưu hàng giờ / hàng ngày / hàng tuần / hàng tháng của tôi ):
$ 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)
Không bao gồm một thư mục lồng nhau:
Ở đây, tôi muốn loại trừ một thư mục lồng nhau, ví dụ: /mnt/Vancouver/projects/ie/claws/data/*
khi tìm kiếm từ /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
Ngoài ra: Thêm -print
vào cuối lệnh sẽ ngăn chặn bản in của thư mục bị loại trừ:
$ 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