Hal yang saya temukan membingungkan -prune
adalah bahwa itu adalah tindakan (seperti -print
), bukan ujian (seperti -name
). Itu mengubah daftar "yang harus dilakukan", tetapi selalu mengembalikan true .
Pola umum untuk menggunakan -prune
adalah ini:
find [path] [conditions to prune] -prune -o \
[your usual conditions] [actions to perform]
Anda hampir selalu menginginkan -o
(logis ATAU) segera setelah itu -prune
, karena bagian pertama dari tes (hingga dan termasuk -prune
) akan mengembalikan false untuk hal-hal yang sebenarnya Anda inginkan (yaitu: hal-hal yang Anda tidak ingin pangkas).
Ini sebuah contoh:
find . -name .snapshot -prune -o -name '*.foo' -print
Ini akan menemukan file "* .foo" yang tidak di bawah direktori ".snapshot". Dalam contoh ini, -name .snapshot
make up [conditions to prune]
, and -name '*.foo' -print
is [your usual conditions]
dan [actions to perform]
.
Catatan penting :
Jika semua yang ingin Anda lakukan adalah mencetak hasil yang mungkin Anda gunakan untuk meninggalkan -print
tindakan. Anda biasanya tidak ingin melakukannya saat menggunakan -prune
.
Perilaku default find adalah "dan" seluruh ekspresi dengan -print
aksi jika tidak ada tindakan selain -prune
(ironisnya) di akhir. Itu artinya menulis ini:
find . -name .snapshot -prune -o -name '*.foo' # DON'T DO THIS
sama dengan menulis ini:
find . \( -name .snapshot -prune -o -name '*.foo' \) -print # DON'T DO THIS
yang berarti itu juga akan mencetak nama direktori yang Anda pangkas, yang biasanya bukan yang Anda inginkan. Alih-alih, lebih baik menentukan -print
tindakan secara eksplisit jika itu yang Anda inginkan:
find . -name .snapshot -prune -o -name '*.foo' -print # DO THIS
Jika "kondisi biasa" Anda cocok dengan file yang juga cocok dengan kondisi prune Anda, file-file itu tidak akan dimasukkan dalam output. Cara untuk memperbaikinya adalah dengan menambahkan-type d
predikat ke kondisi prune Anda.
Sebagai contoh, misalkan kita ingin memangkas direktori yang dimulai dengan .git
(ini diakui agak dibuat - biasanya Anda hanya perlu menghapus hal bernama persis .git
), tetapi selain itu ingin melihat semua file, termasuk file seperti .gitignore
. Anda dapat mencoba ini:
find . -name '.git*' -prune -o -type f -print # DON'T DO THIS
Ini tidak akan termasuk .gitignore
dalam output. Ini versi yang sudah diperbaiki:
find . -name '.git*' -type d -prune -o -type f -print # DO THIS
Kiat tambahan: jika Anda menggunakan versi GNU find
, halaman texinfo untuk find
memiliki penjelasan yang lebih rinci daripada halaman manuvernya (sebagaimana berlaku untuk sebagian besar utilitas GNU).
Laurence Gonsalves
sumber
-prune
tidak hanya bekerja pada direktori (tetapi, untuk direktori, itu juga mencegah memasuki direktori yang cocok dengan kondisi itu, yaitu di sini dirs yang cocok dengan itu-name .snapshot
).-prune
Omong-omong, sebenarnya bukan itu yang menyebabkan ini. Masalahnya adalah bahwa operator atau "korsleting", dan atau memiliki prioritas lebih rendah daripada dan. Hasil akhirnya adalah bahwa jika file yang dipanggil.snapshot
ditemukan akan cocok dengan yang pertama-name
,-prune
maka tidak akan melakukan apa-apa (tapi mengembalikan true), dan kemudian atau mengembalikan true karena argumen kiri itu benar. Tindakan (misalnya:)-print
adalah bagian dari argumen kedua, sehingga tidak pernah memiliki kesempatan untuk mengeksekusi.-print
di akhir, sekarang saya dapat berhenti menambahkan\! -path <pattern>
di samping-prune
Biasanya cara asli kita melakukan hal-hal di linux dan cara kita berpikir dari kiri ke kanan.
Jadi, Anda akan pergi dan menulis apa yang Anda cari terlebih dahulu:
Maka Anda mungkin menekan enter dan menyadari Anda mendapatkan terlalu banyak file dari direktori yang tidak Anda inginkan. Mari kecualikan / media untuk menghindari pencarian drive yang Anda pasang.
Sekarang Anda hanya harus LAMPIRAN berikut ke perintah sebelumnya:
jadi perintah terakhir adalah:
............... | <--- Sertakan ---> | .................... | <- -------- Kecualikan ---------> |
Saya pikir struktur ini jauh lebih mudah dan berkorelasi dengan pendekatan yang tepat
sumber
find
cukup pintar untuk memproses-prune
klausa terlebih dahulu. Hmmm, menarik.-prune
mulai sekarang./media
, memperhatikan bahwa itu tidak dipanggil*.php
dan kemudian memeriksa apakah itu saat ini di dalam/media
, melihat bahwa itu dan karena itu melewatkan seluruh subtree. Itu masih dari kiri ke kanan, itu tidak ada bedanya selama kedua cek tidak tumpang tindih.Waspadalah bahwa -prune tidak mencegah turun ke direktori apa pun seperti yang dikatakan beberapa orang. Itu mencegah turun ke direktori yang cocok dengan tes itu diterapkan. Mungkin beberapa contoh akan membantu (lihat bagian bawah untuk contoh regex). Maaf karena ini sangat panjang.
sumber
find . -name test -prune -o -print
: iow,-prune
adalah tindakan yang juga bekerja pada fileMenambahkan saran yang diberikan dalam jawaban lain (saya tidak punya perwakilan untuk membuat balasan) ...
Saat menggabungkan
-prune
dengan ekspresi lain, ada perbedaan perilaku yang halus tergantung pada ekspresi lain yang digunakan.Contoh @Laurence Gonsalves 'akan menemukan file "* .foo" yang tidak di bawah direktori ".snapshot": -
Namun, tangan pendek yang sedikit berbeda ini akan, mungkin secara tidak sengaja, juga mencantumkan
.snapshot
direktori (dan direktori .snapshot bersarang): -Alasannya adalah (menurut halaman manual pada sistem saya): -
Yaitu, contoh kedua adalah setara dengan memasukkan yang berikut, dengan demikian memodifikasi pengelompokan istilah: -
Ini setidaknya terlihat pada Solaris 5.10. Setelah menggunakan berbagai rasa * nix selama sekitar 10 tahun, saya baru saja mencari alasan mengapa ini terjadi.
sumber
-prune
dengan dan tanpa-print
!Prune adalah jangan berulang di setiap saklar direktori.
Dari halaman manual
Pada dasarnya itu tidak akan masuk ke sub direktori.
Ambil contoh ini:
Anda memiliki direktori berikut
Jika Anda menjalankan
find -name test2
:Ini akan mengembalikan kedua direktori
Jika Anda menjalankan
find -name test2 -prune
:Hanya akan mengembalikan / home / test2 karena tidak akan turun ke / home / test2 untuk menemukan / home / test2 / test2
sumber
Saya bukan ahli dalam hal ini (dan halaman ini sangat membantu bersama dengan http://mywiki.wooledge.org/UsingFind )
Hanya memperhatikan
-path
adalah untuk jalur yang sepenuhnya cocok dengan string / jalur yang datang tepat setelahfind
(.
dalam contoh tesis) di mana-name
cocok dengan semua nama dasar.memblokir direktori .git di direktori Anda saat ini ( seperti temuan Anda
.
)blok semua subdirektori .git secara rekursif.
Perhatikan
./
ini sangat penting !!-path
harus cocok dengan jalur yang dilabuhkan ke.
atau apa pun yang datang setelah menemukan jika Anda mendapatkan kecocokan dengan itu (dari sisi lain atau '-o
') mungkin tidak ada pemangkasan! Saya naif tidak menyadari hal ini dan itu membuat saya menggunakan -path ketika itu bagus ketika Anda tidak ingin memangkas semua subdirektori dengan nama yang sama: Dsumber
find bla/
bla/
*
Tampilkan semuanya termasuk dir itu sendiri tetapi tidak isinya membosankan:
sumber
Jika Anda membaca semua jawaban yang baik di sini, pemahaman saya sekarang adalah bahwa semua jawaban berikut memberikan hasil yang sama:
Tapi yang terakhir akan memakan waktu lebih lama karena masih mencari semuanya di dir1. Saya kira pertanyaan sebenarnya adalah bagaimana caranya
-or
mengeluarkan hasil yang tidak diinginkan tanpa benar-benar mencari mereka.Jadi saya kira prune berarti tidak cocok dengan pertandingan sebelumnya tetapi menandainya sudah selesai ...
http://www.gnu.org/software/findutils/manual/html_mono/find.html "Namun ini bukan karena efek tindakan '-prune' (yang hanya mencegah penurunan lebih lanjut, itu tidak memastikan kita mengabaikan item itu). Alih-alih, efek ini adalah karena penggunaan '-o'. Karena sisi kiri dari kondisi "atau" telah berhasil untuk ./src/emacs, tidak perlu untuk mengevaluasi hak- sisi-tangan ('-cetak') sama sekali untuk file khusus ini. "
sumber
find
membangun daftar file. Ini menerapkan predikat yang Anda berikan untuk masing-masing dan mengembalikan yang lulus.Gagasan ini yang
-prune
berarti mengecualikan dari hasil benar-benar membingungkan bagi saya. Anda dapat mengecualikan file tanpa pangkas:Yang
-prune
dilakukan hanyalah mengubah perilaku pencarian. Jika kecocokan saat ini adalah direktori, dikatakan "heifind
, file yang baru saja Anda cocokkan, jangan turun ke dalamnya" . Itu hanya menghapus pohon itu (tetapi bukan file itu sendiri) dari daftar file yang akan dicari.Itu harus dinamai
-dont-descend
.sumber
Ada beberapa jawaban; beberapa dari mereka terlalu banyak teori-berat. Saya akan meninggalkan mengapa saya perlu memangkas sekali jadi mungkin perlu-pertama / contoh penjelasan berguna bagi seseorang :)
Masalah
Saya punya folder dengan sekitar 20 direktori simpul, masing-masing punya
node_modules
direktori seperti yang diharapkan.Setelah Anda masuk ke proyek apa pun, Anda melihat masing-masing
../node_modules/module
. Tapi Anda tahu bagaimana itu. Hampir setiap modul memiliki dependensi, jadi apa yang Anda lihat lebih miripprojectN/node_modules/moduleX/node_modules/moduleZ...
Saya tidak ingin tenggelam dengan daftar dengan ketergantungan dari ketergantungan ...
Mengetahui
-d n
/-depth n
, itu tidak akan membantu saya, karena direktori node_modules utama / pertama yang saya inginkan dari setiap proyek berada pada kedalaman yang berbeda, seperti ini:Bagaimana saya bisa mendapatkan yang pertama daftar jalan berakhir pada yang pertama
node_modules
dan pindah ke proyek berikutnya untuk mendapatkan yang sama?Memasukkan
-prune
Saat Anda menambahkan
-prune
, Anda akan tetap memiliki pencarian rekursif standar. Setiap "jalan" dianalisis, dan setiap temuan akan dimuntahkan danfind
terus menggali seperti orang yang baik. Tapi ini menggali lebih dalam untuknode_modules
apa yang tidak saya inginkan.Jadi, perbedaannya adalah bahwa di setiap jalur yang berbeda itu,
-prune
akanfind
berhenti menggali lebih jauh ke jalan tertentu ketika telah menemukan item Anda. Dalam kasus saya,node_modules
folder.sumber