Bagaimana menjalankan find -exec?


Jawaban:


710

Anda melewatkan ;(lolos di sini \;untuk mencegah shell mengartikannya) atau a +dan a {}:

find . -exec grep chrome {} \;

atau

find . -exec grep chrome {} +

findakan mengeksekusi grepdan akan mengganti {}dengan nama file yang ditemukan. Perbedaan antara ;dan +adalah bahwa dengan ;satu grepperintah untuk setiap file dieksekusi sedangkan dengan +sebanyak mungkin file diberikan sebagai parameter grepsekaligus.


30
Jika Anda menggunakan \; ending construct grep dilewatkan satu file pada satu waktu, sehingga tidak menampilkan nama file secara default, hanya baris yang cocok. Untuk mendapatkan daftar file, tambahkan saja penggunaan grep -lsdi dalam konstruk find.
Caleb

9
find . -exec grep foo {} +akan menampilkan output seperti ini./dir/file.py:from foo import bar
sg

10
find . -exec grep foo {} \;akan menampilkan output seperti inifrom foo import bar
sg

9
find . -exec grep -l foo {} +akan menampilkan keluaran seperti ini./dir/file.py
sg

8
find . -exec grep -l foo {} \;akan menampilkan output seperti ini./dir/file.py
sg

46

Anda tidak perlu menggunakan findini sama sekali; grep dapat menangani membuka file baik dari daftar gumpalan segala sesuatu di direktori saat ini:

grep chrome *

... atau bahkan secara rekursif untuk folder dan semua yang ada di bawahnya:

grep chrome . -R

22
grep akan tersedak jika ekspansi melampaui ARG_MAX. -R akan mengunjungi semuanya saat menggunakan find, seseorang dapat lebih mudah menambahkan primitif untuk mengecualikan file tertentu (-nama, dll) atau bahkan tidak mengunjungi subtree (-prune).
Mel

6
Poin bagus @Mel. Maksud saya adalah bahwa kemungkinan pihak yang mengajukan membuat hal-hal yang lebih kompleks daripada yang seharusnya dengan memperkenalkan findkapan grepbisa melakukan pekerjaan, tetapi dalam beberapa kasus akan lebih efektif untuk menggunakan menemukan untuk memperbaiki daftar file sebelum pergi keluar untuk grep.
Caleb

4
@Mel greptidak tersedak dalam kasus seperti itu, execya.
Chris Down

Hanya berfungsi jika semua file berada di direktori yang sama, bukan ketika mereka tersebar di subdirektori.
Yaba

1
@Yaba Jawaban saya menyatakan bagaimana menangani kasus file yang tersebar di subdirektori.
Caleb

18
find . | xargs grep 'chrome'

Anda juga dapat melakukan:

find . | xargs grep 'chrome' -ls

Yang pertama menunjukkan kepada Anda baris dalam file, yang kedua hanya daftar file.

Pilihan Caleb lebih rapi, lebih sedikit penekanan tombol.


11
Masalahnya xargsadalah bahwa ia mengharapkan inputnya dikutip dengan cara yang aneh yang findtidak menghasilkan. Jadi find … | xargs …tidak berfungsi jika Anda memiliki nama file yang mengandung spasi atau \'".
Gilles

3
@Gilles Anda bisa menyelesaikan masalah itu dengan menggunakan sesuatu seperti find . | xargs -n1 -iX grep "X" 'chrome'sehingga argumen diberi makan satu per satu dan dikutip. Jelas ini adalah cara yang sangat tidak efisien untuk menangani contoh ini, tetapi untuk beberapa situasi itu bagus.
Caleb

Untuk kelengkapan, kita juga harus menyebutkan opsi -i untuk ketidaksensitifan huruf dengan 'grep'. Juga ada -iname dalam mencari ketidaksensitifan kasus.
Mathew

9
@ Caleb: Satu-satunya cara yang dapat diandalkan 100% untuk xargsmengatasi nama file Linux adalah find ... -print0 | xargs -0, menggunakan NUL sebagai pemisah. Alternatif - xargs -d '\n'menggunakan baris baru sebagai pemisah, keandalan 99%.
grawity

Saya sering menggunakan ini, tetapi akan gagal untuk daftar nama file yang sangat panjang, di mana menemukan -exec menjadi pemenang.
Spacemoose

5

Temukan adalah satu cara dan Anda dapat mencoba the_silver_searchermaka yang perlu Anda lakukan adalah

ag chrome

Ini akan mencari chrome di semua file (termasuk sub direktori) dan lebih cepat daripada menemukan


Ada juga pt (pencari platinum, tersedia di github.com/monochromegane/the_platinum_searcher ) yang, IMHO, melakukan pekerjaan lebih cepat - mungkin tidak masalah jika hanya ada beberapa file.
Hopping Bunny


1

Berikut adalah contoh bagaimana saya biasanya menggunakan find / ...

find  . -name "*.py" -print -exec fgrep hello {} \;

Ini mencari secara rekursif untuk semua file .py, dan untuk setiap file mencetak nama file dan fgrep untuk 'halo' pada file itu (untuk setiap). Outputnya seperti (baru jalankan satu hari ini):

./r1.py
./cgi-bin/tst1.py
print "hello"
./app/__init__.py
./app/views.py
./app/flask1.py
./run.py
./tst2.py
print "hello again"

1
tidak mengacaukan alur kerja Anda, tetapi Anda mungkin ingin: find . -name "*.py" -exec fgrep -l hello {} \; - itu akan mencetak nama file file yang cocok, dan tidak ada yang lain
Jeff Schaller
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.