@ meuh's pendekatan tidak efisien karena -maxdepth 1pendekatannya masih memungkinkan findmembaca isi direktori di level 1 untuk kemudian mengabaikannya sebaliknya. Ini juga tidak akan berfungsi dengan baik dengan beberapa findimplementasi (termasuk GNU find) jika beberapa nama direktori mengandung urutan byte yang tidak membentuk karakter yang valid di lokal pengguna (seperti untuk nama file dalam pengkodean karakter yang berbeda).
find . \( -name . -o -prune \) -extra-conditions-and-actions
adalah cara yang lebih kanonik untuk mengimplementasikan GNU -maxdepth 1(atau FreeBSD -depth -2).
Meskipun demikian, umumnya -depth 1Anda ingin ( -mindepth 1 -maxdepth 1) karena Anda tidak ingin mempertimbangkan .(kedalaman 0), dan kemudian lebih sederhana:
find . ! -name . -prune -extra-conditions-and-actions
Sebab -maxdepth 2, itu menjadi:
find . \( ! -path './*/*' -o -prune \) -extra-conditions-and-actions
Dan di situlah Anda menjalankan masalah karakter yang tidak valid.
Sebagai contoh, jika Anda memiliki direktori bernama Stéphanetetapi yang édikodekan dalam iso8859-1 (alias latin1) charset (0xe9 byte) seperti yang paling umum di Eropa Barat dan Amerika hingga pertengahan 2000-an, maka 0xe9 byte bukan merupakan karakter yang valid dalam UTF-8. Jadi, di lokal UTF-8, *wildcard (dengan beberapa findimplementasi) tidak akan cocok Stéphanedengan *0 karakter atau lebih dan 0xe9 bukan karakter.
$ 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(ketika output masuk ke terminal) menampilkan byte 0xe9 yang tidak valid seperti di ?atas. Anda dapat melihat bahwa St<0xe9>phane/Chazelasitu bukan pruned.
Anda dapat mengatasinya dengan melakukan:
LC_ALL=C find . \( ! -path './*/*' -o -prune \) -extra-conditions-and-actions
Tetapi perhatikan bahwa itu memengaruhi semua pengaturan lokal finddan aplikasi apa pun yang dijalankannya (seperti melalui -execpredikat).
$ LC_ALL=C find . \( ! -path './*/*' -o -prune \)
.
./St?phane
./St?phane/Chazelas
./St??phane
./St??phane/Chazelas
./John
./John/Smith
Sekarang, saya benar-benar mendapatkan -maxdepth 2tetapi perhatikan bagaimana é di Stéphane kedua yang dikodekan dengan benar dalam UTF-8 ditampilkan sebagai ??0xc3 0xa9 byte (dianggap sebagai dua karakter individu yang tidak terdefinisi di C locale) dari pengkodean UTF-8 dari é. tidak dapat dicetak karakter di lokal C.
Dan jika saya telah menambahkan -name '????????', saya akan mendapatkan Stéphane yang salah (yang dikodekan dalam iso8859-1).
Untuk menerapkan jalur yang berubah-ubah ., Anda harus:
find some/dir/. ! -name . -prune ...
untuk -mindepth 1 -maxdepth 1atau:
find some/dir/. \( ! -path '*/./*/*' -o -prune \) ...
untuk -maxdepth 2.
Saya masih akan melakukan:
(cd -P -- "$dir" && find . ...)
Pertama karena itu membuat jalur lebih pendek yang membuatnya kurang mungkin berjalan ke jalur terlalu lama atau daftar arg masalah terlalu lama tetapi juga untuk bekerja di sekitar fakta yang findtidak dapat mendukung argumen jalur sewenang-wenang (kecuali -fdengan FreeBSD find) karena akan tersedak nilai $dirsuka !atau -print...
The -odalam kombinasi dengan negasi adalah trik umum untuk menjalankan dua set independen -condition/ -actiondi find.
Jika Anda ingin menjalankan -action1rapat file -condition1dan secara mandiri -action2rapat file -condition2, Anda tidak bisa melakukan:
find . -condition1 -action1 -condition2 -action2
Seperti -action2hanya akan dijalankan untuk file yang memenuhi kedua kondisi.
Maupun:
find . -contition1 -action1 -o -condition2 -action2
Karena -action2tidak akan dijalankan untuk file yang memenuhi kedua kondisi tersebut.
find . \( ! -condition1 -o -action1 \) -condition2 -action2
berfungsi seperti yang \( ! -condition1 -o -action1 \)akan diselesaikan dengan true untuk setiap file. Itu mengasumsikan -action1adalah tindakan (seperti -prune, -exec ... {} +) yang selalu mengembalikan true . Untuk tindakan seperti -exec ... \;itu dapat mengembalikan false , Anda mungkin ingin menambahkan -o -somethingtempat lain -somethingyang tidak berbahaya tetapi mengembalikan true seperti -truedi GNU findatau -links +0atau -name '*'(meskipun perhatikan masalah tentang karakter yang tidak valid di atas).
-depth -2,-depth 1... pendekatan bisa dilihat sebagai lebih baik dari GNU-maxdepth/-mindepth