Menemukan substring dalam file di seluruh subdirektori dengan satu perintah bawaan?

10

Di Windows, jika saya ingin menemukan string di semua file di semua subdirektori, saya akan melakukan sesuatu seperti

findstr /C:"the string" /S *.h

Namun, di Linux (katakanlah, Ubuntu) saya telah menemukan ada cara lain selain beberapa perintah pipa yang melibatkan find, xargsdan grep(contoh adalah di halaman ini: ? Bagaimana saya bisa rekursif grep melalui sub-direktori ). Namun, pertanyaan saya berbeda: apakah ada perintah tunggal yang terpasang melalui sulap ini, tanpa harus menulis skrip shell saya?

Guido Domenici
sumber

Jawaban:

19

GNU grep memungkinkan pencarian secara rekursif melalui subdirektori:

grep -r --include='*.h' 'the string' .
mengibaskan
sumber
Saya mencoba baris perintah yang tepat ini di Ubuntu tetapi mendapatkan "grep: opsi tidak valid - 'M'" walaupun saya tidak dapat melihat 'M' di mana pun ... membingungkan
Guido Domenici
@ Guido Bekerja dengan baik di sini
phunehehe
Dalam edit yang disarankan, TomasG menyarankan untuk mengubah yang terakhir *ke '*': "Mengutip wildcard terakhir diperlukan untuk menghindari kesalahan ketika beberapa nama file dimulai dengan -"
Michael Mrozek
Dalam peristiwa yang aneh, sekarang juga bekerja untuk saya, seperti yang dimasukkan dalam jawaban asli. Terima kasih!
Guido Domenici
1
@ Guido: Masalah Anda mungkin karena file di direktori saat ini dipanggil -Msomething, atau karena GREP_OPTIONSpengaturan.
Gilles 'SO- stop being evil'
2

grep -r searchpattern /path/to/start/in

Di mana /path/to/start/in/" ." hanya bisa untuk direktori saat ini.

mattdm
sumber
1

Tidak. find -name \*.h -print0 | xargs -0 grep -l 'the regex'Sama ajaibnya.

glenn jackman
sumber
GNU grep memiliki case umum bawaan dengan -ropsinya. Tidak perlu artileri berat.
Gilles 'SO- stop being evil'
3
xargsmenambahkan hanya kebisingan. Gunakanfind -name \*.h -execdir grep -l 'the regex {} +
pengguna tidak diketahui
0

apakah ada perintah bawaan tunggal yang berfungsi melalui sihir ini ...?

Untuk menjadi bertele-tele, tidak, Anda tidak dapat menganggap perintah seperti itu ada .

Ada banyak implementasi Unix yang berbeda, dan masing-masing memiliki kebiasaan yang berbeda. POSIX, penyebut yang umum (dan hal yang paling dekat dengan standar di seluruh Unices) tidak menentukan opsi seperti itu untukgrep .

Seperti disebutkan dalam jawaban lain, implementasi GNU grepmemiliki opsi non-standar yang melakukan apa yang Anda inginkan. Walaupun implementasi khusus ini mungkin umum pada sistem Linux, Anda tidak dapat mengasumsikan ketersediaannya pada Unix apa pun, bahkan pada beberapa sistem Linux.

Akhirnya, saya harus menyebutkan bahwa itu adalah filosofi Unix untuk mendukung kombinasi beberapa program primitif, daripada penggunaan satu executable monolitik besar yang mencoba melakukan semuanya sekaligus.

Dalam kasus Anda, merayapi sistem file dan mencocokkan regexp dalam aliran adalah dua tugas terpisah. Adalah normal untuk memperlakukan masing-masing dalam program yang terpisah.

rahmu
sumber
0

Untuk menemukan string dari direktori yang diberikan gunakan perintah di bawah ini

find <fullDirectoryPath> -name '*' -exec grep -l '<StringToFind>' {} \;

Sebagai contoh:

find /apps_bev/apps/xfer/export/02210 -name '*' -exec grep -l '38221000001032' {} \;
Yogesh
sumber
1
grepdapat mengambil lebih dari satu file sebagai argumen, jadi Anda harus menggunakan +alih-alih \;menghindari menjalankan satu greppermintaan per file yang cukup tidak efisien.
Stéphane Chazelas
1
Catatan yang -name '*'membatasi file yang namanya teks yang valid di lokal saat ini ( findsetidaknya dalam beberapa implementasi), tetapi komponen direktori lainnya mungkin masih mengandung urutan byte yang tidak membentuk karakter yang valid. Jika maksud Anda dengan itu -name '*'adalah untuk memastikan output teks yang valid (dengan menghilangkan file dengan nama yang tidak benar), Anda lebih suka menggunakan find ... ! -name '*' -prune -o -exec grep ... {} +, yang juga akan berhenti findturun ke direktori dengan nama yang tidak benar.
Stéphane Chazelas