find
(untuk -name
/ -path
predikat standar) menggunakan pola wildcard seperti gumpalan (perhatikan bahwa {a,b}
bukan operator gumpal; setelah ekspansi, Anda mendapatkan dua gumpalan). Perbedaan utama adalah penanganan garis miring (dan file titik dan direktori tidak diperlakukan secara khusus find
). *
dalam gumpalan tidak akan menjangkau beberapa direktori. */*/*
akan menyebabkan hingga 2 level direktori terdaftar. Menambahkan -path './*/*/*'
akan cocok dengan semua file yang memiliki setidaknya 3 level dan tidak akan berhenti find
dari daftar isi direktori apa pun pada kedalaman apa pun.
Untuk itu
./foo*bar/quux[A-Z]{.bak,}/pic[0-9][0-9][0-9][0-9]?.jpg
beberapa gumpalan, mudah untuk menerjemahkan, Anda menginginkan direktori pada kedalaman 3, sehingga Anda dapat menggunakan:
find . -mindepth 3 -maxdepth 3 \
\( -path './foo*bar/quux[A-Z].bak/pic[0-9][0-9][0-9][0-9]?.jpg' -o \
-path './foo*bar/quux[A-Z]/pic[0-9][0-9][0-9][0-9]?.jpg' \) \
-exec cmd {} +
(atau -depth 3
dengan beberapa find
implementasi). Atau POSIXly:
find . -path './*/*/*' -prune \
\( -path './foo*bar/quux[A-Z].bak/pic[0-9][0-9][0-9][0-9]?.jpg' -o \
-path './foo*bar/quux[A-Z]/pic[0-9][0-9][0-9][0-9]?.jpg' \) \
-exec cmd {} +
Yang akan menjamin itu *
dan ?
tidak bisa cocok dengan /
karakter.
( find
, bertentangan dengan gumpalan akan membaca isi direktori selain dari foo*bar
yang ada di direktori saat ini¹, dan tidak mengurutkan daftar file. Tetapi jika kita mengesampingkan masalah apa yang cocok dengan [A-Z]
atau perilaku *
/ ?
berkaitan dengan karakter yang tidak valid adalah tidak ditentukan, Anda akan mendapatkan daftar file yang sama).
Tetapi bagaimanapun juga, seperti yang telah ditunjukkan oleh @muru , tidak perlu menggunakan find
jika hanya untuk membagi daftar file menjadi beberapa proses untuk mengatasi batas execve()
panggilan sistem. Beberapa kerang seperti zsh
(dengan zargs
) atau ksh93
(dengan command -x
) bahkan memiliki dukungan bawaan untuk itu.
Dengan zsh
(yang gumpalannya juga setara dengan -type f
dan sebagian besar find
predikat lainnya ), misalnya:
autoload zargs # if not already in ~/.zshrc
zargs ./foo*bar/quux[A-Z](|.bak)/pic[0-9][0-9][0-9][0-9]?.jpg(.) -- cmd
(Apakah (|.bak)
operator glob bertentangan dengan {,.bak}
, (.)
kualifikasi glob adalah setara find
dengan -type f
, tambahkan oN
di sana untuk melewati pengurutan seperti dengan find
, D
untuk memasukkan file dot (tidak berlaku untuk glob ini))
¹ Agar find
dapat merayapi pohon direktori seperti yang akan terjadi, Anda memerlukan sesuatu seperti:
find . ! -name . \( \
\( -path './*/*' -o -name 'foo*bar' -o -prune \) \
-path './*/*/*' -prune -name 'pic[0-9][0-9][0-9][0-9]?.jpg' -exec cmd {} + -o \
\( ! -path './*/*' -o -name 'quux[A-Z]' -o -name 'quux[A-Z].bak' -o -prune \) \)
Itu memangkas semua direktori pada level 1 kecuali foo*bar
yang, dan semua pada level 2 kecuali quux[A-Z]
atau quux[A-Z].bak
yang, lalu pilih pic...
yang di level 3 (dan memangkas semua direktori di level itu).
-path
atau-ipath
.find . -path './foo*bar/quux[A-Z]/pic[0-9][0-9][0-9][0-9]?.jpg'
harus bekerja - kecuali itu akan cocok/fooz/blah/bar/quuxA/pic1234d.jpg
. Apakah itu akan menjadi masalah?