Cách tiếp cận của @ meuh không hiệu quả vì -maxdepth 1cách tiếp cận của anh ấy vẫn cho phép findđọc nội dung của các thư mục ở cấp 1 để sau đó bỏ qua chúng. Nó cũng sẽ không hoạt động đúng với một số findtriển khai (bao gồm GNU find) nếu một số tên thư mục chứa chuỗi byte không tạo thành các ký tự hợp lệ trong miền địa phương của người dùng (như đối với tên tệp trong mã hóa ký tự khác).
find . \( -name . -o -prune \) -extra-conditions-and-actions
là cách thức kinh điển hơn để triển khai GNU -maxdepth 1(hoặc FreeBSD -depth -2).
Nói chung, mặc dù, đó là điều -depth 1bạn muốn ( -mindepth 1 -maxdepth 1) vì bạn không muốn xem xét .(độ sâu 0), và sau đó nó thậm chí còn đơn giản hơn:
find . ! -name . -prune -extra-conditions-and-actions
Vì -maxdepth 2, điều đó trở thành:
find . \( ! -path './*/*' -o -prune \) -extra-conditions-and-actions
Và đó là nơi bạn chạy trong các vấn đề nhân vật không hợp lệ.
Chẳng hạn, nếu bạn có một thư mục được gọi Stéphanenhưng éđược mã hóa trong bộ ký tự iso8859-1 (còn gọi là latin1) (0xe9 byte) như phổ biến nhất ở Tây Âu và Mỹ cho đến giữa những năm 2000, thì byte 0xe9 đó không phải là một ký tự hợp lệ trong UTF-8. Vì vậy, trong các ngôn ngữ UTF-8, *ký tự đại diện (với một số findtriển khai) sẽ không khớp Stéphanevới *0 hoặc nhiều ký tự và 0xe9 không phải là ký tự.
$ locale charmap
UTF-8
$ find . -maxdepth 2
.
./St?phane
./St?phane/Chazelas
./Stéphane
./Stéphane/Chazelas
./John
./John/Smith
$ find . \( ! -path './*/*' -o -prune \)
.
./St?phane
./St?phane/Chazelas
./St?phane/Chazelas/age
./St?phane/Chazelas/gender
./St?phane/Chazelas/address
./Stéphane
./Stéphane/Chazelas
./John
./John/Smith
My find(khi đầu ra đi đến một thiết bị đầu cuối) hiển thị byte 0xe9 không hợp lệ như ?trên. Bạn có thể thấy đó St<0xe9>phane/Chazelaskhông phải là pruned.
Bạn có thể làm việc xung quanh nó bằng cách làm:
LC_ALL=C find . \( ! -path './*/*' -o -prune \) -extra-conditions-and-actions
Nhưng lưu ý rằng điều đó ảnh hưởng đến tất cả các cài đặt ngôn ngữ findvà bất kỳ ứng dụng nào nó chạy (như thông qua các -execvị từ).
$ LC_ALL=C find . \( ! -path './*/*' -o -prune \)
.
./St?phane
./St?phane/Chazelas
./St??phane
./St??phane/Chazelas
./John
./John/Smith
Bây giờ, tôi thực sự nhận được một -maxdepth 2lưu ý rằng é trong Stéphane thứ hai được mã hóa chính xác trong UTF-8 được hiển thị dưới ??dạng các byte 0xc3 0xa9 (được coi là hai ký tự không xác định riêng lẻ trong ngôn ngữ C) của mã hóa UTF-8 không in các ký tự trong miền địa phương C.
Và nếu tôi đã thêm một -name '????????', tôi sẽ nhận được Stéphane sai (cái được mã hóa trong iso8859-1).
Để áp dụng cho các đường dẫn tùy ý thay vì ., bạn sẽ làm:
find some/dir/. ! -name . -prune ...
cho -mindepth 1 -maxdepth 1hoặc:
find some/dir/. \( ! -path '*/./*/*' -o -prune \) ...
cho -maxdepth 2.
Tôi vẫn sẽ làm một:
(cd -P -- "$dir" && find . ...)
Đầu tiên bởi vì điều đó làm cho các đường dẫn ngắn hơn khiến nó ít có khả năng chạy vào đường dẫn quá dài hoặc liệt kê các vấn đề quá dài mà còn khắc phục được thực tế là findkhông thể hỗ trợ các đối số đường dẫn tùy ý (ngoại trừ -fvới FreeBSD find) vì nó sẽ bị nghẹt giá trị $dirthích !hoặc -print...
Sự -okết hợp với phủ định là một mẹo phổ biến để chạy hai bộ -condition/ -actionin độc lập find.
Nếu bạn muốn chạy -action1trên cuộc họp tệp -condition1và độc lập -action2với cuộc họp tệp -condition2, bạn không thể thực hiện:
find . -condition1 -action1 -condition2 -action2
Như -action2sẽ chỉ được chạy cho các tập tin đáp ứng cả hai điều kiện.
Cũng không:
find . -contition1 -action1 -o -condition2 -action2
Như -action2sẽ không được chạy cho các tập tin đáp ứng cả hai điều kiện.
find . \( ! -condition1 -o -action1 \) -condition2 -action2
hoạt động như \( ! -condition1 -o -action1 \)sẽ giải quyết đúng cho mọi tập tin. Giả định đó -action1là một hành động (như -prune, -exec ... {} +) luôn trả về đúng . Đối với những hành động như -exec ... \;có thể trả lại sai , bạn có thể muốn thêm một -o -somethingnơi -somethinglà vô hại nhưng trả về đúng như -truetrong GNU findhay -links +0hay -name '*'(mặc dù lưu ý các vấn đề về nhân vật không hợp lệ ở trên).
-depth -2,-depth 1... có thể được xem là tốt hơn so với GNU-maxdepth/-mindepth