grep, tetapi hanya ekstensi file tertentu

966

Saya sedang bekerja menulis beberapa skrip ke grepdirektori tertentu, tetapi direktori ini berisi semua jenis file.

Saya ingin grepadil .hdan .cppuntuk saat ini, tetapi mungkin beberapa orang lain di masa depan.

Sejauh ini saya punya:

{ grep -r -i CP_Image ~/path1/;

grep -r -i CP_Image ~/path2/;

grep -r -i CP_Image ~/path3/;

grep -r -i CP_Image ~/path4/;

grep -r -i CP_Image ~/path5/;} 

| mailx -s GREP [email protected]

Adakah yang bisa menunjukkan kepada saya bagaimana saya sekarang akan menambahkan hanya ekstensi file tertentu?

Jason
sumber
13
Sudah mencoba grep -r -i CP_Image ~/path1/*.{h,cpp}?
8
Gunakan The Silver Searcher : ag -i CP_Image ~/path[1-5] | mailx -s GREP [email protected]. Pekerjaan selesai.
Johnsyweb
Gunakan egrep (kemungkinan besar sudah diinstal sebelumnya pada sistem Anda), dan kemudian Anda bisa menggunakan regex.
Dogweather
8
Orang-orang GNU benar-benar kacau ketika mereka menambahkan -runtuk grepmencari file karena melanggar mantra UNIX memiliki alat yang "melakukan satu hal dan melakukannya dengan baik". Ada alat yang sangat baik untuk menemukan file dengan nama yang SANGAT jelas.
Ed Morton

Jawaban:

1354

Cukup gunakan --includeparameter, seperti ini:

grep -r -i --include \*.h --include \*.cpp CP_Image ~/path[12345] | mailx -s GREP [email protected]

yang harus melakukan apa yang Anda inginkan.

Untuk mengambil penjelasan dari jawaban HoldOffHunger di bawah ini:

  • grep: perintah

  • -r: secara rekursif

  • -i: abaikan-kasing

  • --include \*.cpp: all * .cpp: file C ++ (lolos dengan \ kalau-kalau Anda memiliki direktori dengan tanda bintang di nama file)

  • ./: Mulai di direktori saat ini.

Nelson
sumber
123
Sebagai catatan: -r (rekursif) -i (abaikan kasus) - sertakan (cari hanya file yang cocok dengan pola file)
Luis
34
Lebih lanjut dapat dioptimalkan kegrep -r -i --include \*.h --include \*.cpp CP_Image ~/path[12345]
zwol
1
@Hong mana dokumentasi yang -R untuk tautan simbolik?
titus
8
Contoh ini tampaknya memiliki skor tinggi karena mencakup berbagai kemungkinan tetapi jawaban yang diberikan di bawah grep -r --include = *. Txt 'searchterm' ./ benar-benar menjelaskan inti dari jawaban
David Casper
10
mengapa tidak menggunakan tanda kutip ganda sebagai ganti backslash? mis:grep -r -i --include="*.h" --include="*.cpp" CP_Image
pambda
283

Beberapa jawaban ini sepertinya terlalu sintaksis, atau mereka menghasilkan masalah pada Server Debian saya. Ini bekerja dengan baik untuk saya:

PHP Revolution: Bagaimana cara Grep file di Linux, tetapi hanya ekstensi file tertentu?

Yaitu:

grep -r --include=\*.txt 'searchterm' ./

... atau versi tidak sensitif-huruf ...

grep -r -i --include=\*.txt 'searchterm' ./
  • grep: perintah

  • -r: secara rekursif

  • -i: abaikan-kasing

  • --include: all * .txt: file teks (lepas dengan \ kalau-kalau Anda memiliki direktori dengan tanda bintang di nama file)

  • 'searchterm': Apa yang harus dicari

  • ./: Mulai di direktori saat ini.

HoldOffHunger
sumber
7
Anda harus menghindari *penggunaan \*.cppatau '*.cpp'. Kalau tidak, itu tidak akan memberikan hasil yang diharapkan ketika direktori kerja berisi beberapa *.txtfile.
Melebius
@Melebius dapat Anda jelaskan mengapa perlu melarikan diri - apakah ada hubungannya dengan ekstensi CPP atau TXT yang Anda sebutkan? Atau apakah Anda hanya menggunakan itu sebagai contoh?
Simon East
2
@SimonEast Ekstensi ini adalah ekstensi yang digunakan dalam pertanyaan dan jawaban ini, tidak ada yang istimewa selain itu. Ini mungkin akan bekerja tanpa melarikan diri ketika menggunakan --include=<pattern>tetapi penting untuk melarikan diri *dengan --include <pattern>(ruang bukannya =) yang terasa sangat mirip.
Melebius
52
grep -rnw "some thing to grep" --include=*.{module,inc,php,js,css,html,htm} ./
Yuri Malov
sumber
3
grep -rn "some to to grep" --include = *. {module, inc, c, h} *
ashish
3
Jawaban bagus. Lebih bersih daripada yang diterima di IMO tetapi Anda harus menambahkan kriteria pencarian seperti yang dicatat
@ashish
mengapa --includeopsi setelah jarum, tidak dengan opsi lain?
vladkras
@vladkras, apa maksudmu jarum? Apakah itu --?
heretoinfinity
50

Bagaimana tentang:

find . -name '*.h' -o -name '*.cpp' -exec grep "CP_Image" {} \; -print
Amir Afghani
sumber
5
saya sarankan mengelompokkan -nameargumen - argumen itu. hal-hal aneh dapat terjadi jika Anda tidak melakukannya. find . \( -name '*.h' -o -name '*.cpp' \) -exec grep "CP_Image" {} \; -print
nullrevolution
gunakan dengan "-type f" tambahan untuk mengabaikan semua objek direktori, hanya tertarik pada file.
kensai
1
Saya menggunakan metode ini selama bertahun-tahun dan itu berhasil tetapi itu BANYAK lebih lambat daripada grep rekursif karena exec menemukan memunculkan proses grep terpisah untuk setiap file yang akan dicari.
beaudet
Mengatasi komentar @ beaudet, findsecara opsional dapat menggabungkan argumen, mengurangi pemanggilan proses yang dipanggil ke minimum. find . \( -name \*.h -o -name \*.cpp \) -exec grep -H CP_Image {} + Ini disarankan tetapi tidak disorot dalam jawaban @ fedorqui di bawah ini dan merupakan peningkatan yang bermanfaat. The -Hargumen untuk grep di sini adalah berguna ketika menemukan hanya mengidentifikasi file yang cocok tunggal. Ini bisa menghilangkan penggunaan -printdalam jawaban. Jika daftar total file Anda cukup kecil, menggunakan glob shell rekursif (mis. {path1,path2}/**/*.{cpp,h}) Mungkin lebih disukai.
Malcolm
19

Tidak ada opsi -r pada server HP dan Sun, cara ini bekerja untuk saya di server HP saya

find . -name "*.c" | xargs grep -i "my great text"

-i adalah untuk pencarian string yang tidak sensitif

Sam B
sumber
1
Saya telah menemukan beberapa server untuk perusahaan hosting web yang tidak memiliki opsi --incangkan yang tersedia untuk fgrep dan ini adalah baris perintah yang saya gunakan dalam contoh tersebut.
Borgboy
Opsi --include juga tidak tersedia saat menggunakan Git untuk Windows (MinGW / MSys).
Darren Lewis
@ DarrenLewis tersedia di Git Bash untuk Windows. Tapi anehnya, itu menambahkan alias berwarna-warni seperti lltapi tidak menambah --color=autogrep.
Xeverous
Ini harus menjadi jawaban yang diterima untuk kelengkapan, portabilitas, dan singkatnya!
Grant Foster
12

Karena ini adalah masalah menemukan file, mari kita gunakan find!

Menggunakan GNU find, Anda dapat menggunakan -regexopsi untuk menemukan file-file itu di pohon direktori yang ekstensinya adalah .hatau .cpp:

find -type f -regex ".*\.\(h\|cpp\)"
#            ^^^^^^^^^^^^^^^^^^^^^^^

Kemudian, itu hanya masalah mengeksekusi greppada setiap hasilnya:

find -type f -regex ".*\.\(h\|cpp\)" -exec grep "your pattern" {} +

Jika Anda tidak memiliki distribusi ini, Anda harus menggunakan pendekatan seperti Amir Afghan , gunakan -ountuk menggabungkan opsi ( nama diakhiri dengan .hatau dengan.cpp ):

find -type f \( -name '*.h' -o -name '*.cpp' \) -exec grep "your pattern" {} +
#            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Dan jika Anda benar-benar ingin menggunakan grep, ikuti sintaks yang ditunjukkan untuk --include:

grep "your pattern" -r --include=*.{cpp,h}
#                      ^^^^^^^^^^^^^^^^^^^
fedorqui 'SO berhenti merugikan'
sumber
7

Cara termudah adalah

find . -type  f -name '*.extension' | xargs grep -i string 
pengguna3640130
sumber
3

ag (pencari perak) memiliki sintaks yang cukup sederhana untuk ini

       -G --file-search-regex PATTERN
          Only search files whose names match PATTERN.

begitu

ag -G *.h -G *.cpp CP_Image <path>
Eldamir
sumber
menggunakan ag 2.2.0, saya harus meletakkan bendera saya terakhir:ag _string_to_find_ -G _filename_regex_
ryanrain
3

Jawaban di bawah ini bagus:

grep -r -i --include \*.h --include \*.cpp CP_Image ~/path[12345] | mailx -s GREP [email protected]

Tetapi dapat diperbarui ke:

grep -r -i --include \*.{h,cpp} CP_Image ~/path[12345] | mailx -s GREP [email protected]

Yang bisa lebih sederhana.

hao
sumber
1

Harus menulis "-exec grep" untuk setiap "-o -name"

find . -name '*.h' -exec grep -Hn "CP_Image" {} \; -o -name '*.cpp' -exec grep -Hn "CP_Image" {} \;

Atau kelompokkan mereka dengan ()

find . \( -name '*.h' -o -name '*.cpp' \) -exec grep -Hn "CP_Image" {} \;

opsi '-Hn' menunjukkan nama file dan baris.

dimana23
sumber
1

Saya sadar pertanyaan ini agak ketinggalan zaman, tetapi saya ingin membagikan metode yang biasanya saya gunakan untuk menemukan file .c dan .h :

tree -if | grep \\.[ch]\\b | xargs -n 1 grep -H "#include"

atau jika Anda memerlukan nomor baris juga:

tree -if | grep \\.[ch]\\b | xargs -n 1 grep -nH "#include"
Tom
sumber