grep semua file .java di direktori untuk string tertentu

12

Bagaimana saya mencari semua file .java untuk string sederhana (bukan regex) di direktori saat ini dan semua sub-direktori pada Mac OS X? Saya hanya ingin mencetak daftar nama file dan direktori yang cocok.

John Topley
sumber
Terima kasih telah menanyakan ini, jadi saya tidak perlu. Sekarang saya hanya perlu mencari cara untuk mengecualikan "git" dan saya sudah selesai untuk sedikit.
Dan Rosenstark
Saya pikir jawaban js lebih ringkas, masih menyebalkan Anda harus mengetik - termasuk, tapi tetap saja. Mungkin bisa saja menulis alias untuk menyembunyikannya
Craig Tataryn

Jawaban:

19

Dan selalu populer

find . -name '*.java' | xargs grep -l 'string'

EDIT (oleh Frank Szczerba):

Jika Anda berurusan dengan nama file atau direktori yang memiliki spasi di dalamnya, cara teraman untuk melakukannya adalah:

find . -name '*.java' -print0 | xargs -0 grep -l 'string'

Selalu ada lebih dari satu cara untuk melakukannya.

David Mackintosh
sumber
11

Jawaban tradisional UNIX adalah jawaban yang diterima untuk pertanyaan ini:

find . -name '*.java' | xargs grep -l 'string'

Ini mungkin akan berfungsi untuk file Java, tetapi spasi dalam nama file jauh lebih umum di Mac daripada di dunia UNIX tradisional. Ketika nama file dengan spasi dilewatkan melalui pipa di atas, xargs akan menafsirkan kata-kata individual sebagai nama yang berbeda.

Yang Anda inginkan adalah memisahkan nama untuk membuat batas-batas menjadi tidak ambigu:

find . -name '*.java' -print0 | xargs -0 grep -l 'string'

Alternatifnya adalah membiarkan find menjalankan grep untuk Anda, seperti yang disarankan Mark, meskipun pendekatan itu lebih lambat jika Anda mencari sejumlah besar file (karena grep dipanggil sekali per file daripada sekali dengan seluruh daftar file).

Frank Szczerba
sumber
Anda juga dapat menggunakan opsi "--replace" di xargs untuk menangani nama file yang memiliki spasi di dalamnya: ... | xargs --replace grep 'string' '{}' ({} akan diganti dengan nama file)
arathorn
1
Versi modern find (termasuk yang terinstal di OS X) mendukung "-exec <command> {} +" di mana tanda plus di akhir (bukan \;) memberi tahu find untuk mengganti {} dengan "sebanyak mungkin nama path. ... Ini mirip dengan xargs (1) "(dari halaman manual).
Doug Harris
7

Gunakan grep yang lebih baik daripada grep, ack :

ack -l --java  "string" 
bortzmeyer
sumber
3
ack tidak diinstal pada Mac OS X secara default.
John Topley
Saya tidak tahu apa artinya "secara default". Pada banyak OS, Anda memilih apa yang Anda instal sehingga sulit untuk menemukan program yang selalu ada. Pada suatu waktu, kompiler C selalu ada di sana dan Perl jarang ...
bortzmeyer
1
Ini berarti bahwa itu adalah bagian dari instalasi OS standar. Saya memiliki alat pengembang yang diinstal pada Mac saya dan mereka tidak menginstal ack. Anda harus menginstalnya sendiri. Jika Anda memilikinya, maka itu adalah sintaks yang bagus.
John Topley
Dalam kasus ack, ini adalah program Perl tunggal tanpa dependensi modul. Jika Anda dapat "menginstal" program di direktori ~ / bin Anda, maka Anda dapat dengan mudah "menginstal" ack.
Andy Lester
4

Ini sebenarnya akan menggunakan regex jika Anda mau, tinggal jauh dari metakarakter, atau lepas darinya, dan Anda bisa mencari string.

find . -iname "*.java" -exec egrep -il "search string" {} \;

Mark Thalman
sumber
3
grep -rl --include="*.java" simplestring *
js.
sumber
1
Ini tampaknya menjadi jawaban terbaik di sini - jika grep melakukan semuanya, mengapa menggunakan find & xargs?
Peter Gibson
FYI, mengingat apa yang ditanyakan dalam pertanyaan, seharusnya kecil "Aku" tidak besar "L" dalam perintah itu
Craig Tataryn
Craig benar, saya mengoreksi jawaban saya.
js.
1

Karena ini adalah pertanyaan OSX, inilah jawaban yang lebih spesifik untuk OSX.

Lewati finddan gunakan Spotlightdari baris perintah. Jauh lebih kuat!

COMMAND LINE SPOTLIGHT - TEMUKAN TEMUKAN GREP

Kebanyakan orang tidak tahu Anda bisa melakukan pencarian Spotlight dari baris perintah. Mengapa ingat semua opsi menemukan dan menangkap misterius dan apa yang tidak ketika Anda dapat membiarkan Spotlight melakukan pekerjaan untuk Anda. Antarmuka baris perintah ke Spotlight disebut mdfind. Ia memiliki semua kekuatan yang sama dengan pencarian Spotlight GUI dan lebih banyak lagi karena scriptable di baris perintah!


sumber
0

Coba ini:

grep -rl "string" */*java
dwj
sumber
1
Ini memberikan "grep: * / * java: Tidak ada file atau direktori" di Mac OS X.
John Topley
Masalahnya di sini adalah bahwa ia hanya akan menemukan file * .java sedalam satu tingkat. Lihat jawaban Mark Thalman untuk IMHO cara yang tepat untuk melakukannya.
Ludwig Weinzierl
Maaf, bukan di Mac saya. Bukankah versi grep Mac memiliki flag -r (recursive)?
dwj
Memang, tapi itu adalah output yang saya dapatkan ketika mencari string yang saya tahu ada di file.
John Topley
0

Anda juga bisa menggunakan program GUI seperti TextWrangler untuk melakukan pencarian yang lebih intuitif di mana opsi ada di antarmuka.

Mark Thalman
sumber
0
grep "(your string)" -rl $(find ./ -name "*.java")

Jika Anda ingin mengabaikan case, ganti -rl dengan -irl. (string Anda) juga bisa menjadi regex jika Anda pernah melihat kebutuhannya.

laughing_man
sumber