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@domain.com

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


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@domain.com. 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@domain.com

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.


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.


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} ./

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

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


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}
#                      ^^^^^^^^^^^^^^^^^^^


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>

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@domain.com

Tetapi dapat diperbarui ke:

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

Yang bisa lebih sederhana.


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.


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"
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.