grep、ただし特定のファイル拡張子のみ


966

スクリプトをgrep特定のディレクトリに書き込む作業をしていますが、これらのディレクトリにはあらゆる種類のファイルタイプが含まれています。

私がしたいgrepだけ.h.cpp、今のところ、しかし、将来的には、おそらくいくつかの他の。

これまでのところ:

{ 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

特定のファイル拡張子だけを追加する方法を誰かに教えてもらえますか?


13
試しましたgrep -r -i CP_Image ~/path1/*.{h,cpp}か?

8
シルバーサーチャーを使う:ag -i CP_Image ~/path[1-5] | mailx -s GREP email@domain.com。仕事が終わりました。
Johnsyweb 2013年


egrepを使用して(ほとんどの場合、システムにプリインストールされています)、次に正規表現を使用できます。
Dogweather 2013年

8
GNUの連中は、ファイルを検索するように追加-rしたときに本当に混乱しましたgrep。これは、「1つのことを行うだけで十分に機能する」ツールを使用するというUNIXのマントラを壊すためです。非常にわかりやすい名前のファイルを見つけるための完全に優れたツールがあります。
Ed Morton

回答:


1354

次のように--includeパラメータを使用するだけです。

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

それはあなたが望むことをするはずです。

以下のHoldOffHungerの答えから説明を取得するには:

  • grep:コマンド

  • -r:再帰的に

  • -i:大文字小文字を区別しない

  • --include \*.cpp:すべての* .cpp:C ++ファイル(ファイル名にアスタリスクが含まれるディレクトリがある場合に備えて、\でエスケープします)

  • ./:現在のディレクトリから開始します。


123
レコードの場合:-r(再帰的)-i(大文字と小文字を区別しない)
Luis

34
さらに最適化できるgrep -r -i --include \*.h --include \*.cpp CP_Image ~/path[12345]
zwol 2013年

1
@Hong -Rがシンボリックリンク用のドキュメントはどこにありますか?
titus

8
この例は、非常に広い範囲の可能性をカバーしているため、高いスコアを持っているようですが、以下のgrep -r --include = *。txt 'searchterm' ./の答えは、答えの本質を実際に説明しています
David Casper

10
バックスラッシュの代わりに二重引用符を使用しないのはなぜですか?例:grep -r -i --include="*.h" --include="*.cpp" CP_Image
pambda 2017

283

これらの回答の一部は構文が多すぎるようでした、または私のDebianサーバーで問題が生じました。これは私にとって完璧に機能しました:

PHP革命:LinuxでファイルをGrepする方法、ただし特定のファイル拡張子のみ?

つまり:

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

...または大文字と小文字を区別しないバージョン...

grep -r -i --include=\*.txt 'searchterm' ./
  • grep:コマンド

  • -r:再帰的に

  • -i:大文字小文字を区別しない

  • --include:すべての* .txt:テキストファイル(ファイル名にアスタリスクが含まれるディレクトリがある場合に備えて、\でエスケープします)

  • 'searchterm':検索対象

  • ./:現在のディレクトリから開始します。


7
または*を使用してエスケープする必要があります。そうしないと、作業ディレクトリにいくつかのファイルが含まれている場合、期待した結果が得られません。\*.cpp'*.cpp'*.txt
メレビウス2017年

@Melebiusはなぜエスケープが必要なのか説明できますか-言及したCPPまたはTXT拡張機能と何か関係がありますか?それとも例としてそれらを使用しましたか?
Simon East

2
@SimonEastこれらの拡張機能は、この質問と回答で使用される拡張機能であり、他に特別なものはありません。使用時にエスケープせずに動作する可能--include=<pattern>性がありますが、それ以外は非常によく似ている(の代わりにスペース)でエスケープ*することが重要です。--include <pattern>=
Melebius

52
grep -rnw "some thing to grep" --include=*.{module,inc,php,js,css,html,htm} ./

3
grep -rn "something to grep" --include = *。{module、inc、c、h} *
ashish

3
いい答えだ。IMOで承認されたものよりもきれいですが、@ ashishが指摘したように検索条件を追加する必要があります
Billynoah

--include他のオプションではなく、なぜ針の後にオプションがあるのですか?
vladkras

@vladkras、針ってどういう意味?ですよ--ね?
heretoinfinity

50

どうですか:

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

5
これらの-name引数をグループ化することをお勧めします。そうしないと、奇妙なことが起こります。find . \( -name '*.h' -o -name '*.cpp' \) -exec grep "CP_Image" {} \; -print
nullrevolution 2012

追加の「-type f」と一緒に使用して、ファイルのみに関心があるすべてのディレクトリオブジェクトを無視します。
ケンサイ2017年

1
私はこの方法を何年も使用しましたが、機能しますが、findのexecは検索するファイルごとに個別のgrepプロセスを生成するため、再帰的なgrepよりもかなり低速です。
ボーデット

@beaudetのコメントをfind処理すると、オプションで引数をバンドルできるため、呼び出されたプロセスの呼び出しを最小限に抑えることができます。 find . \( -name \*.h -o -name \*.cpp \) -exec grep -H CP_Image {} + これは推奨されますが、以下の@fedorquiの回答では強調表示されていません。価値のある改善です。-Hここでのgrep の引数は、findが一致するファイルを1つだけ識別する場合に役立ちます。これは-print、回答での使用を排除する可能性があります。ファイルの合計リストが十分に小さい場合は、再帰的なシェルグロブ(例:)を使用することをお勧めします{path1,path2}/**/*.{cpp,h}
マルコム

19

HPおよびSunサーバーには-rオプションはありません。この方法は、私のHPサーバーでは機能しました。

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

-iは、大文字と小文字を区別しない文字列の検索用です


1
私は、fgrepに--includeオプションを使用できないWebホスティング会社向けのサーバーをいくつか見つけました。これが、これらのインスタンスで使用するコマンドラインです。
Borgboy 2016年

Git for Windows(MinGW / MSys)を使用している場合、-includeオプションも使用できません。
ダレンルイス

@DarrenLewisはGit Bash for Windowsで利用できます。しかし、奇妙なことに、grepにllは追加さ--color=autoれませんが、grepには追加されません。
Xeverous、

これは、完全性、移植性、および簡潔さのために受け入れられる答えになるはずです!
Grant Foster

12

これはファイルの検索の問題なので、使用してみましょうfind

GNUは、使用できます使用して-regexのいずれかの拡張子のディレクトリのツリーでそれらのファイルを見つけるために、オプションをされます.h.cpp

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

次に、grepその結果のそれぞれで実行するだけです。

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

このfindの分布がない場合は、オプションを連結するために使用するAmir Afghaniのようなアプローチを使用する必要が-oあります(名前の末尾が.hかである.cpp):

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

そして、本当に使用したい場合grepは、以下に示す構文に従って--includeください。

grep "your pattern" -r --include=*.{cpp,h}
#                      ^^^^^^^^^^^^^^^^^^^

7

最も簡単な方法は

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

3

ag (シルバーサーチャー)の構文はかなり単純です。

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

そう

ag -G *.h -G *.cpp CP_Image <path>

AG 2.2.0を使用して、私は最後に私の旗を置くために必要な:ag _string_to_find_ -G _filename_regex_
ryanrain

3

以下の答えは良いです:

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

ただし、次のように更新できます。

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

これはもっと簡単なことです。


1

「-o -name」ごとに「-exec grep」と書き込む必要があります

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

または()でグループ化する

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

オプション '-Hn'は、ファイル名と行を表示します。


1

この質問は少し古くなっていることは承知していますが、.cおよび.hファイルを見つけるために通常使用する方法を共有したいと思います。

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

または、行番号も必要な場合:

tree -if | grep \\.[ch]\\b | xargs -n 1 grep -nH "#include"
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.