Bagaimana cara menghentikan pencarian agar tidak masuk ke direktori yang ditemukan?

24

Saya ingin menemukan semua direktori dengan string tertentu sehingga saya dapat melakukan pencarian lain pada file yang ada di dalamnya.

Jadi saya tidak ingin membuang waktu, ./my-search-term/dir/my-search-termdll.

Bagaimana saya bisa berhenti berulang ketika saya telah menemukan direktori istilah pencarian saya yang pertama?

Stephen
sumber
3
Sudahkah Anda mencoba mencari dengan -prune? Dari halaman manual: "jika file tersebut adalah direktori, jangan turun ke dalamnya. Jika -depth diberikan, false; tidak ada efek. Karena -hapus berarti -depth, Anda tidak dapat menggunakan -prune dan -delete secara berguna."
laebshade
1
@laebshade mengapa Anda tidak menjawabnya?
jw013
@ jw013 Saya tidak punya waktu untuk memberikan jawaban yang lebih mendalam saat itu.
laebshade

Jawaban:

17

The -prunetindakan membuat findtidak recurse ke dalam direktori. Anda dapat menggabungkannya dengan tindakan lain seperti -exec(urutan -prunedan -exectidak masalah, asalkan -prunedieksekusi bagaimanapun juga).

find . -name my-search-term -prune -exec find {} … \;

Perhatikan bahwa bersarang finddi dalam a find -execbisa sedikit bermasalah: Anda tidak dapat menggunakan -execdi bagian dalam find, karena terminator akan dilihat sebagai terminator oleh bagian luar find. Anda dapat mengatasinya dengan menggunakan shell, tetapi jangan mengutip.

find . -name my-search-term -prune -exec sh -c '
    find "$@" … -exec … {\} +
' _ {} +
Gilles 'SANGAT berhenti menjadi jahat'
sumber
Apakah tanda kurung dalam perintah pertama Anda perlu? -prunemengembalikan true dan dapat diletakkan sebelum -exec.
rozcietrzewiacz
@rozcietrzewiacz Tidak, itu tidak perlu. Kebiasaan memiliki -odi sana, kurasa. Dan saya kira menempatkan -prunesebelumnya -execlebih mudah dibaca.
Gilles 'SO- stop being evil'
Terima kasih, tidak menggunakan -pruneopsi sebelumnya.
haridsv
Dalam kasus penggunaan saya, perintah ini: mkdir -p x1 x2; touch x1/x11 x1/x12 x2/x21 x2/x22; find . -name 'x1*' -exec rm -rf {} \;memberikan kesalahan: find: ./x1: No such file or directory. Solusinya adalah menambahkan -prunedi akhir findperintah.
haridsv
(1) Beberapa versi findmemperluas {}bahkan ketika muncul sebagai substring dari suatu argumen -exec. Versi seperti itu findakan mencekik perintah kedua Anda, karena perintah {}di dalam find(di perintah shell) akan diganti dengan nama direktori yang ditemukan di bagian luar find. Anda dapat memperbaikinya dengan mengatakan find . -name my-search-term -prune -exec sh -c 'find "$0" … -exec … "{"} +' {} \; mis. Menggunakan "{"}, di mana shell akan berubah menjadi {}. ... (Lanjutan)
Scott
6

- solusi terbuka -

Jika Anda ingin findmelewatkan konten direktori yang ditemukan, tetapi terus mencari di direktori lain, gunakan -pruneseperti yang disarankan @laebshade. Perintah lengkapnya akan terlihat seperti

 find . -type d -name somename -prune -exec ...

Di sisi lain, jika Anda ingin finduntuk sepenuhnya berhenti mencari dan setelah menemukan direktori yang cocok pertama, maka apa yang Anda cari adalah -quit(tersedia sejak versi 4.2.3dari GNU find). Yang ini sedikit lebih rumit untuk digunakan, karena ia findlangsung keluar - jadi -quitharus ditempatkan di bagian paling akhir dari perintah:

find . -type d -name somename -exec ... -quit

Agar ini berfungsi seperti yang diharapkan, kita harus memastikan bahwa -execpengembalian benar (dengan kata lain, status nol ). Jika Anda ingin status keluar -execdiabaikan, sehingga -quitselalu berfungsi, Anda perlu sedikit trik:

find . -type d -name somename \( -exec ... -o -true \) -quit

atau

find . -type d -name somename \( -exec ... -o -quit \)

atau

find . -type d -name somename \( -exec ... , -quit \) # a comma before -quit

- beberapa penjelasan -

Hal terpenting tentang cara findkerjanya adalah bahwa semua tindakan ("tes") diperlakukan sebagai predikat logis yang ditafsirkan dari kiri ke kanan. Oleh karena itu, tindakan terakhir (misalnya -quit) hanya akan dilakukan jika seluruh bagian sebelumnya tidak mengembalikan false . Secara default, semua tes digabungkan dengan "DAN" yang logis, -oopsi mengubah sambungan menjadi "ATAU".

Elemen yang rumit -oadalah yang finddapat "mengoptimalkan" perintah Anda dan tidak menjalankan -execbagian jika Anda mengetikkan saja

find . -type d -name somename -exec ... -o -quit

Untuk mengatasinya, Anda dapat memaksa finduntuk mengevaluasi semua predikat yang digabung dengan "ATAU", dengan melampirkannya di dalam tanda kurung.

rozcietrzewiacz
sumber