再帰grep:特定のディレクトリを除外


49

特定のコンテンツを持つソースファイルを見つけるために、再帰的なgrepを頻繁に使用します。

grep -Rni "myfunc" .

大規模なコードベースでは、これは遅くなる可能性があるため、--incldueを使用して拡張機能を制限/ホワイトリストに登録します。

grep -Rni --include=*.java "myfunc" .

ただし、サブディレクトリ全体を除外(プルーニング)する方が効率的です。

grep -Rni --exclude=/.svn/ "myfunc" .

ただし、--excludeは上記の* .javaのようなファイルパターンのみをサポートします。ディレクトリを除外するにはどうすればよいですか?

回答:


10

あなたはackを調べるかもしれません。

使い始めたばかりですが、これには適しているようです。


ackはかなり良さそうです。不要なファイルを直感的に除外できるのは素晴らしいことです。--nogroupオプションは、grep -Rni
gabor

2
Ackは少し遅いです。シルバーサーチャー(Ag)またはripgrep(rg)を試すことができます。
user31389

62
grep -r --exclude-dir=dev --exclude-dir=sys --exclude-dir=proc PATTERN data

ソース:https : //stackoverflow.com/questions/2799246/grep-exexcept-a-specific-folder-using


17
これは再帰的に除外することに注意してください。./devとともに除外され./foo/bar/devます。--exclude-dir=./dev最初のケースにのみ適用するために使用します。
コリーウォーカー

4
グロビングによってこれを少し短くすることもできます。グロビング bash grep -r --exclude-dir={dev,sys,proc} PATTERN data の唯一の問題は、bashで動作させられないことです。その場合、それらを分離しておく必要があります。
b01

3
また、{}は複数のエントリを配置した場合にのみ機能することに注意してください。つまり、-exclude-dir = {home、.svn}は機能しますが、-exclude-dir = {。svn}は機能しません。そもそも1つのエントリでテストするため、{}が機能しない理由を理解するのに時間がかかります。
林果皞

{}単一のエントリで使用する場合、おそらく配列にするために単項コンマが必要です(Bashがそれをどのように処理するかはわかりません)。それを行う代わりに、私はいつも除外したいフォルダーのリストをループするエイリアスを.bash_aliasesに作成することになりました。例えば、.git、.svn、.hg、.cache、そしてループで追加します--exclude-dir $dirそして、その配列をgrepエイリアスに展開します。
dragon788

6

代わりにfindを使用できます。

find . -not -path "*/.svn*" -not -type d -exec grep -ni "myfunc" {} \; -print

OK、それでは少し逆になります。最初にgrepの結果を取得し、次にパスを取得します。たぶん他の誰かがより良い答えを持っていますか?


3
わかりました、私はそれがとても好きです。もちろん、findははるかに柔軟です。出力の唯一の違いは、「grep -Rni」が各一致のファイル名を出力するのに対して、「find -exec grep」は各行にファイル名を出力し、次に各一致の行名と行内容を出力することです。 )。「grepの-Hni」勢力各ライン上に表示されるファイル名を使用して
ガボール

grepの--exclude-dirをせずに、この無愛想なシステムのために働いていた唯一の答えを提供してくれてありがとう、まだで働いたことがお奨め
ドミトリDB

2

これは私のプロジェクトのスクリプトの完全な例です。このファイルを「all_source」(実行可能としてマーク)と呼び、プロジェクトのルートディレクトリに配置grep myfunc $(./all_source)してから、スクリプトの最後のソートが完全にそうであるように呼び出します。オプション。

#!/bin/bash

find . \
    -type d \( \
            -wholename './lib' -o \
            -wholename './vc6' -o \
            -name 'gen' -o \
            -name '.svn' \
            \) -prune -o \
    -type f \( \
            -name '*.h' -o \
            -name '*.cpp' -o \
            -name '*.c' -o \
            -name '*.lua' -o \
            -name '*.*awk' \) -print \
    | sort

このスクリプトは、一致するプロジェクト内のすべてのファイル名を返しますが、*.h, *.cpp, *.c, *.lua, *.*awk.svnおよびgenフォルダーという名前のすべてのフォルダーを検索するのではなく、./liband のフォルダーをスキップしません./vc6(ただし、プロジェクトルートのすぐ下のフォルダーのみ)。そのgrep myfunc $(./all_source)ため、これらのファイルのみを参照します。プロジェクトのルートディレクトリからもこれを呼び出す必要があります。


0

以下を見つけるための-pruneオプションもあります。

 find . -path "*/.svn*" -prune -o -not -type d -exec grep -ni "myfunc" {} \; -print

0

これを試すことができます:

grep -R  "myfunc" . | grep -v path_to_exclude/

例:ログファイルのコンテンツを検索したくない場合は、次の手順を実行します。

grep -R "myfunc" . | grep -v log/
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.