Bagaimana menjalankan find -exec?

477

Saya ingin mencari file di direktori saat ini yang berisi teks "chrome".

$ find . -exec grep chrome
find: missing argument to `-exec'

Apa yang saya lakukan salah?

ripper234
sumber
Saya mendapatfind: Only one instance of {} is supported with -exec ... +
Costa
2
Terkait: Cara menggunakan -execdenganfind
Kusalananda

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.

bmk
sumber
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
Caleb
sumber
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.

Mathew
sumber
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

Tanya dan Belajar
sumber
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

Untuk melihat daftar file, bukan baris:

grep -l "chrome" *

atau:

grep -r -l "chrome" .
mateusz.szymborski
sumber
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"
jon
sumber
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