どうすればgrep -Rからディレクトリを除外できますか?


667

「node_modules」ディレクトリ以外のすべてのサブディレクトリをトラバースしたい。


3
参照してくださいsuperuser.com/q/66715/59933
borrible

14
「man grep」と入力するだけで、-excludeおよび--exclude-dirオプションがすぐに表示されます-この質問の見出しから、私はすでにgrepについて知っていると思います...
arcseldon

34
gitリポジトリのコードをgrep node_modulesしていて.gitignore、にいる場合git grep "STUFF"は、これが最も簡単な方法です。git grep作業ツリー内の追跡されたファイルを検索し、次のものをすべて無視します.gitignore
0xcaff

2
:ノードのための例grep -R --exclude-dir={node_modules,bower_components} "MyString" | cut -c1-"$COLUMNS"..「nodegrep」またはものは何でも、常にこのエイリアスシェルで、あなたは可能性が、さらに、文字列の入力としてコマンド引数を使用-
bshea

回答:


394

SOLUTION 1(組み合わせるfindgrep

このソリューションの目的は、grepパフォーマンスを処理することではなく、ポータブルソリューションを示すことです。ビジーボックスまたは2.5より古いバージョンのGNUでも動作するはずです。

findディレクトリfooおよびbarを除外するには、を使用します。

find /dir \( -name foo -prune \) -o \( -name bar -prune \) -o -name "*.sh" -print

次に、ポータブルソリューションとして、findとの非再帰的使用を組み合わせgrepます。

find /dir \( -name node_modules -prune \) -o -name "*.sh" -exec grep --color -Hn "your text to find" {} 2>/dev/null \;

ソリューション2(の再帰的使用grep):

このソリューションはすでにご存じですが、最新かつ効率的なソリューションであるため、追加します。これは移植性の低いソリューションですが、人間が読める形式です。

grep -R --exclude-dir=node_modules 'some pattern' /path/to/search

複数のディレクトリを除外するには、次のように使用--exclude-dirします。

--exclude-dir={node_modules,dir1,dir2,dir3}

ソリューション3(Ag)

コードを頻繁に検索する場合、Ag(The Silver Searcher)はgrepのはるかに高速な代替手段であり、コードの検索用にカスタマイズされています。たとえば、にリストされているファイルとディレクトリは自動的に無視される.gitignoreので、同じやっかいな除外オプションをgrepやに渡し続ける必要はありませんfind


2
この組み合わせはより速く検索し、--exclude-dir=dir結果を色で表示します-読みやすい
Maxim Yefremov

27
「この組み合わせ」find ... -execgrep --exclude-dir私より速くはありません。あなたは置き換えない限り、(HDD上の38K +の除外26K +ファイルで約5倍の速さ)をgrepする巨大な利点\;+検索/ execのコンボ用。その場合、grepは約30%速くなります。grep構文も人間が読める形式です:)。
Kjell Andreassen 14年

これは明白なので同意しました。一部のbusyboxesにはGREPコマンドがありません。
hornetbzz

10
また、複数を除外できることに注意してください--exclude-dir={dir1,dir2}
suh

4
node_modules標準的な例である私は、少しも驚いていません。
pdoherty926

981

GNU Grepの最近のバージョン(> = 2.5.2)は以下を提供します:

--exclude-dir=dir

これは、パターンに一致するdirディレクトリを再帰的なディレクトリ検索から除外します。

だからあなたはできる:

grep -R --exclude-dir=node_modules 'some pattern' /path/to/search

構文と使用法の詳細については、

古いGNU GrepsとPOSIX Grepについてfindは、他の回答で提案されているように使用してください。

または単にackEdit:またはThe Silver Searcher)を使用して、それで終わります!


4
@マノチョー:ackすばらしいと思うなら、シルバーサーチャーを試して、速度が上がるのを見てください!
Johnsyweb 2013年

30
せっかちな人のための構文:シェルのファイルグロビングではなく、の正規表現パターンを--exclude-dir=dir使用します。パターンは、現在のディレクトリからの相対パスで機能します。したがって、パターンではなくパターンを使用してください。grep--exclude-dir=dir--exclude-dir="/root/dir/*"
タニアス2014

15
検索から複数のディレクトリを除外したい場合は、次のオプションを使用するよりも優れたオプションがあります$ grep -r --exclude-dir=dir1 --exclude-dir=dir2 "string" /path/to/search/dirか?
Darshan Chaudhary 2015年

4
私はおそらくこれまでに正気の人よりも多くの時間を費やしましたが、私の人生の中で、サブディレクトリを検索から除外する方法を理解することはできません- grep -r --exclude-dir=public keyword .動作しますが、grep -r --exclude-dir='public/dist' keyword .動作しません。正規表現のワイルドカードや文字のエスケープなどを追加しようとしましたが、何も役に立たないようです。
dkobozev 2016

72
:そうのような複数のディレクトリを除外するgrep -r "Request" . --exclude-dir={node_modules,git,build}
maverick97

77

複数のディレクトリを除外する場合:

"r"は再帰的、 "l"は一致を含むファイルの名前のみを出力し、 "i"は大文字と小文字の区別を無視します。

grep -rli --exclude-dir={dir1,dir2,dir3} keyword /path/to/search

例:「hello」という単語を含むファイルを検索したい。procディレクトリ、ブートディレクトリ、sysディレクトリ、ルートディレクトリを除く すべてのLinuxディレクトリ検索したい:

grep -rli --exclude-dir={proc,boot,root,sys} hello /

注:上記の例はrootである必要があります

注2(@skplunkerinによる):のコンマの後にスペースを追加しないでください {dir1,dir2,dir3}


5
注:カンマの後にスペースを追加しないでください{dir1,dir2,dir3}
skplunkerin

おかげで、便利なSVNのワークスペースを通じてgrep'ing:grep -Irsn --exclude-dir=.svn 'foo' .
RAM237

1
あなただけ提供することができます--exclude-dirオプションを複数回。
ワルフ2017

44

この構文

--exclude-dir={dir1,dir2}

これではなく、シェル(Bashなど)によって次のように展開さgrepれます。

--exclude-dir=dir1 --exclude-dir=dir2

引用すると、シェルがそれを拡張するのを防ぐため、これは機能しません。

--exclude-dir='{dir1,dir2}'    <-- this won't work

で使用される--exclude-dirパターンは、--excludeオプションのマニュアルページで説明されているパターンと同じ種類です。

--exclude=GLOB
    Skip files whose base name matches GLOB (using wildcard matching).
    A file-name glob can use *, ?, and [...]  as wildcards, and \ to
    quote a wildcard or backslash character literally.

シェルは通常、そのようなパターン自体を拡張しようとするため、これを回避するには、引用する必要があります。

--exclude-dir='dir?'

次のように、中括弧と引用符で囲まれた除外パターンを一緒に使用できます。

--exclude-dir={'dir?','dir??'}

パターンは複数のパスセグメントにまたがることができます。

--exclude-dir='some*/?lse'

これはのようなディレクトリを除外しtopdir/something/elseます。


13

これを頻繁に使用します。

grep-r(再帰的)、i(大文字と小文字を区別しない)、-o(行の一致する部分のみを出力する)と組み合わせて使用​​できます。files使用を除外--excludeし、ディレクトリを除外するには、を使用します--exclude-dir

まとめると、次のような結果になります。

grep -rio --exclude={filenames comma separated} \
--exclude-dir={directory names comma separated} <search term> <location>

説明すると、実際よりもはるかに複雑に聞こえます。簡単な例で説明する方が簡単です。

例:

debuggerデバッグセッション中に文字列値を明示的に設定したすべての場所で現在のプロジェクトを検索していて、確認/削除したいとします。

私はと呼ばれるスクリプトを書き、すべての出現を見つけるためにfindDebugger.sh使用grepします。しかしながら:

ファイルの除外について-それ.eslintrcが無視されることを確認したいと思います(これには実際にはリンティングルールがあるdebuggerため、除外する必要があります)。同様に、自分のスクリプトが結果で参照されないようにします。

ディレクトリの除外の場合- node_modules参照するライブラリがたくさん含まれておりdebugger、それらの結果には興味がないので除外します。また、これらの検索場所も気にしないので.idea.gitディレクトリを省略して非表示にし、検索のパフォーマンスを維持したいと考えています。

だからここに結果があります-私はと呼ばれるスクリプトを作成しますfindDebugger.sh

#!/usr/bin/env bash
grep -rio --exclude={.eslintrc,findDebugger.sh} \
--exclude-dir={node_modules,.idea,.git} debugger .

「r」オプションは大文字の「-R」で印刷する必要があると思います。
hornetbzz 2018年

1
面白い。「r」は常にnixとmacで機能してきました。
arcseldon 2018年

私が答えを書いたとき、私はそれを使用しました-R(今はなぜか思い出せません)。私は通常使用します-r。大文字バージョンはシンボリックリンクに従います。TIL。
Johnsyweb

@Johnsyweb-ありがとう。あなたの回答に賛成しました-おそらく思い出せません、おそらく2016年にこれを追加したときです:)
arcseldon

10

あなたは次のようなことを試すことができます grep -R search . | grep -v '^node_modules/.*'


34
場合によっては、このような良い解決策ではありません。例:「node_modules」ディレクトリが偽陽性の一致が多い巨大なディレクトリである場合(そのため、ディレクトリを除外する必要がある)、最初のgrepはサブディレクトリを検索するのに多くの時間を浪費し、次に2番目のgrepフィルタリング試合から。最初のgrep自体でnode_modulesを除外する方が高速です。
GuruM

2
私は遅いことは気にしない、コマンドを見てそれが何をするかを知ることができる
Funkodebat

1
グルのコメントに対する同上。私の場合、/varヒット/var/runしたときにgrepがハングします。したがって、そもそもディレクトリを避けたい理由です。
jww 2015

3
--exclude-dirは2016
Omar Tariq

10

gitリポジトリのコードをgrep node_modulesしていて.gitignore、にいる場合は、を使用できますgit grepgit grep作業ツリーで追跡されたファイルを検索します。.gitignore

git grep "STUFF"

これは非常に便利なヒントです。ありがとうございます。
NKM 2019年

4

特に「node_modules」内の検索を避けたいNode.jsを扱うユーザーにとっては非常に便利です。

find ./ -not -path "*/node_modules/*" -name "*.js" | xargs grep keyword

2

簡単な作業コマンド:

root/dspace# grep -r --exclude-dir={log,assetstore} "creativecommons.org"

上記では、現在のディレクトリ「dspace」でテキスト「creativecommons.org」をgrepし、dirs {log、assetstore}を除外しています。

できました。


かっこ内のいくつかのディレクトリを含むきちんとした
ミジョー

2

多くの正しい答えはここに与えられているが、私は前に失敗するいくつか急い試みを引き起こした一点を強調するために、この1を追加している:exclude-dir取るパターンではなく、ディレクトリへのパスを。

検索が次のようになっているとします。

grep -r myobject

また、出力がからの結果で乱雑になっていることがわかりますsrc/other/objects-folder。このコマンドはなりませんあなたが意図した結果を与えます:

grep -r myobject --exclude-dir=src/other/objects-folder

そして、あなたはなぜexclude-dirうまくいかないのか疑問に思うかもしれません!実際にから結果を除外するにはobjects-folder、次のようにします。

grep -r myobject --exclude-dir=objects-folder

つまり、パスではなくフォルダ名のみを使用します。あなたがそれを知っていれば明らかです。

manページから:

--exclude-dir = GLOB
パターンGLOBに一致する名前サフィックスを持つコマンドラインディレクトリをスキップします。再帰的に検索する場合は、ベース名がGLOBと一致するサブディレクトリをスキップしてください。GLOBの余分な末尾のスラッシュを無視します。


2

これは私にとってはうまくいきます:

grep <stuff> -R --exclude-dir=<your_dir>

5
この回答は、すでに投稿されているものとどのように異なりますか?
aexl 2017


-1

より簡単な方法は、「grep -v」を使用して結果をフィルタリングすることです。

grep -i needle -R * | grep -v node_modules


12
これは、3年前にDipSwitchが提供した回答と実質的に同じです。同じ問題があります。
jww 2015
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.