@ meuh's pendekatan tidak efisien karena -maxdepth 1
pendekatannya masih memungkinkan find
membaca isi direktori di level 1 untuk kemudian mengabaikannya sebaliknya. Ini juga tidak akan berfungsi dengan baik dengan beberapa find
implementasi (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 1
Anda 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éphane
tetapi 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 find
implementasi) tidak akan cocok Stéphane
dengan *
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/Chazelas
itu bukan prune
d.
Anda dapat mengatasinya dengan melakukan:
LC_ALL=C find . \( ! -path './*/*' -o -prune \) -extra-conditions-and-actions
Tetapi perhatikan bahwa itu memengaruhi semua pengaturan lokal find
dan aplikasi apa pun yang dijalankannya (seperti melalui -exec
predikat).
$ 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 2
tetapi 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 1
atau:
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 find
tidak dapat mendukung argumen jalur sewenang-wenang (kecuali -f
dengan FreeBSD find
) karena akan tersedak nilai $dir
suka !
atau -print
...
The -o
dalam kombinasi dengan negasi adalah trik umum untuk menjalankan dua set independen -condition
/ -action
di find
.
Jika Anda ingin menjalankan -action1
rapat file -condition1
dan secara mandiri -action2
rapat file -condition2
, Anda tidak bisa melakukan:
find . -condition1 -action1 -condition2 -action2
Seperti -action2
hanya akan dijalankan untuk file yang memenuhi kedua kondisi.
Maupun:
find . -contition1 -action1 -o -condition2 -action2
Karena -action2
tidak 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 -action1
adalah tindakan (seperti -prune
, -exec ... {} +
) yang selalu mengembalikan true . Untuk tindakan seperti -exec ... \;
itu dapat mengembalikan false , Anda mungkin ingin menambahkan -o -something
tempat lain -something
yang tidak berbahaya tetapi mengembalikan true seperti -true
di GNU find
atau -links +0
atau -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