862

foo=ディレクトリ ツリー内のテキスト ファイル内の文字列を探しています。これは一般的な Linux マシン上にあり、bash シェルがあります。

grep -ircl "foo=" *

ディレクトリには、一致する多くのバイナリ ファイルもあります"foo="。これらの結果は関連性がなく、検索が遅くなるため、grep でこれらのファイル (主に JPEG および PNG 画像) の検索をスキップする必要があります。どうすればいいですか?

--exclude=PATTERNとオプションがあることは知ってい--include=PATTERNますが、パターン形式は何ですか? grep のマニュアルページには次のように書かれています。

--include=PATTERN     Recurse in directories only searching file matching PATTERN.
--exclude=PATTERN     Recurse in directories skip file matching PATTERN.

grep includegrep include excludegrep exclude 、およびバリアントを検索しても、関連するものが見つかりませんでした

特定のファイルだけを grep するより良い方法があれば、私は大歓迎です。問題のあるファイルを移動することはできません。特定のディレクトリだけを検索することはできません (ディレクトリ構造は非常に混乱しており、すべてがどこにでもあります)。また、何もインストールできないため、一般的なツール ( grepや提案されたfindなど) を使用する必要があります。

4

22 に答える 22

874

シェルグロビング構文を使用します。

grep pattern -r --include=\*.cpp --include=\*.h rootdir

の構文--excludeは同じです。

スターは、シェルによって展開されないようにバックスラッシュでエスケープされていることに注意してください ( のようにスターを引用して--include="*.cpp"も同様に機能します)。それ以外の場合、現在の作業ディレクトリにパターンに一致するファイルがある場合、コマンド ラインは のような形式に展開され、 およびgrep pattern -r --include=foo.cpp --include=bar.cpp rootdirという名前のファイルのみが検索されますが、これはおそらく希望どおりではありません。foo.cppbar.cpp

2021-03-04 更新

元の回答を編集して、このようなパターンを簡素化するために Bash や zsh などのいくつかのシェルによって提供される機能であるブレース展開の使用を削除しました。ただし、ブレース展開は POSIX シェルに準拠していないことに注意してください。

元の例は次のとおりです。

grep pattern -r --include=\*.{cpp,h} rootdir

.cppディレクトリにルートされているすべての.hファイルを検索しますrootdir

于 2008-10-21T13:44:01.793 に答える
229

バイナリ ファイルだけをスキップしたい場合は、-I(大文字の i) オプションを検討することをお勧めします。バイナリ ファイルは無視されます。私は定期的に次のコマンドを使用します。

grep -rI --exclude-dir="\.svn" "pattern" *

再帰的に検索し、バイナリ ファイルを無視し、Subversion の隠しフォルダーの中を探しません。どのようなパターンでも構いません。職場のボックスで「grepsvn」というエイリアスを付けています。

于 2008-10-21T14:12:04.623 に答える
72

まさにこれらの状況向けに設計されたackをご覧ください。あなたの例

grep -ircl --exclude=*.{png,jpg} "foo=" *

ack asで行われます

ack -icl "foo="

ack はデフォルトでバイナリ ファイルを検索せず、 -r はデフォルトでオンになっているためです。CPP と H ファイルのみが必要な場合は、次のようにします。

ack -icl --cpp "foo="
于 2008-10-21T14:18:19.400 に答える
36

grep 2.5.3 は、--exclude-dir希望どおりに機能するパラメーターを導入しました。

grep -rI --exclude-dir=\.svn PATTERN .

環境変数を設定することもできます。GREP_OPTIONS="--exclude-dir=\.svn"

Andy のackへの投票を支持しますが、それが最高です。

于 2009-02-04T18:41:39.567 に答える
30

久しぶりにこれを見つけました。次のように複数の包含と除外を追加できます。

grep "z-index" . --include=*.js --exclude=*js/lib/* --exclude=*.min.js
于 2012-12-20T04:54:44.537 に答える
13

提案されたコマンド:

grep -Ir --exclude="*\.svn*" "pattern" *

--exclude はベース名で機能するため、概念的に間違っています。つまり、現在のディレクトリの .svn のみをスキップします。

于 2008-12-17T18:56:38.317 に答える
11

grep 2.5.1 では、この行を ~/.bashrc または ~/.bash プロファイルに追加する必要があります

export GREP_OPTIONS="--exclude=\*.svn\*"
于 2010-04-01T10:13:14.727 に答える
8

grep の出力を grep すると非常に役立つ場合があります。

grep -rn "foo=" . | grep -v "Binary file"

ただし、バイナリ ファイルの検索が実際に停止するわけではありません。

于 2008-10-21T13:44:45.973 に答える
7

の使用を嫌がらない場合はfind、その-prune機能 が気に入っています。

find [directory] \
        -name "pattern_to_exclude" -prune \
     -o -name "another_pattern_to_exclude" -prune \
     -o -name "pattern_to_INCLUDE" -print0 \
| xargs -0 -I FILENAME grep -IR "pattern" FILENAME

最初の行で、検索するディレクトリを指定します。.(現在のディレクトリ) は、たとえば有効なパスです。

2 行目と 3 行目では、、、、などを使用し"*.png"ます。これらの構造体は、パターンと同じ数だけ使用してください。"*.gif""*.jpg"-o -name "..." -prune

4 行目では、別のパターン-o("or" を に指定find) が必要であり、必要なパターンであり、最後に-printorが必要です。、など -print0の画像を削除した後に残る「その他すべて」が必要な場合は、 を使用して 4 行目で完了です。*.gif*.png-o -print0

xargs最後に、5 行目は、結果の各ファイルを受け取り、変数に格納するパイプですFILENAME。次にgrep-IRフラグを渡し、によって展開されて、 によって検出されたファイル名のリストになります。"pattern"FILENAMExargsfind

特定の質問について、ステートメントは次のようになります。

find . \
     -name "*.png" -prune \
     -o -name "*.gif" -prune \
     -o -name "*.svn" -prune \
     -o -print0 | xargs -0 -I FILES grep -IR "foo=" FILES

于 2011-11-14T20:41:29.233 に答える
7

CentOS 6.6/Grep 2.6.3 では、次のように使用する必要があります。

grep "term" -Hnir --include \*.php --exclude-dir "*excluded_dir*"

等号「=」がないことに注意してください (それ以外の場合、、、--includeおよび--excludeinclude-dir無視--exclude-dirされます) 。

于 2014-11-07T18:43:19.663 に答える
5

私は好事家ですが、 ~/.bash_profile は次のようになります。

export GREP_OPTIONS="-orl --exclude-dir=.svn --exclude-dir=.cache --color=auto" GREP_COLOR='1;32'

2 つのディレクトリを除外するには、 --exclude-dir を 2 回使用する必要があることに注意してください。

于 2009-08-27T06:02:29.330 に答える
3

find と xargs はあなたの友達です。grep の --exclude ではなく、それらを使用してファイル リストをフィルタリングします。

次のようなものを試してください

find . -not -name '*.png' -o -type f -print | xargs grep -icl "foo="

これに慣れることの利点は、他のユース ケースに拡張できることです。たとえば、すべての非 png ファイルの行数をカウントする場合などです。

find . -not -name '*.png' -o -type f -print | xargs wc -l

すべての非 png ファイルを削除するには:

find . -not -name '*.png' -o -type f -print | xargs rm

コメントで指摘されているように、一部のファイルの名前にスペースが含まれている可能性がある場合は、代わりに-print0andを使用してください。xargs -0

于 2008-10-21T13:45:26.893 に答える
3

これを試してください:

$ 検索します。-name "*.txt" -type f -print | xargs ファイル | grep "foo=" | カット -d: -f1

ここに設立: http://www.unix.com/shell-programming-scripting/42573-search-files-except-binary-files.html

于 2008-10-21T13:54:13.677 に答える
2

これらのスクリプトはすべての問題を解決するわけではありません...これをもっとよく試してください:

du -ha | grep -i -o "\./.*" | grep -v "\.svn\|another_file\|another_folder" | xargs grep -i -n "$1"

このスクリプトは、ディレクトリの検索を回避するために「実際の」正規表現を使用するため、非常に優れています。フォルダ名またはファイル名を「\|」で区切るだけです grep-vで

楽しめ!私のLinuxシェルで見つかりました!XD

于 2008-11-05T08:30:45.060 に答える
2

@これを見てください。

grep --exclude="*\.svn*" -rn "foo=" * | grep -v Binary | grep -v tags
于 2010-11-10T05:11:55.040 に答える
1

--binary-files=without-matchGNU へのオプションは、grepバイナリ ファイルをスキップするようにします。-I(他の場所で言及されているスイッチと同等です。)

(これには の最新バージョンが必要になる場合がありgrepます。少なくとも 2.5.3 には含まれています。)

于 2009-04-06T11:15:46.977 に答える
1

tcsh .alias ファイルに適しています:

alias gisrc 'grep -I -r -i --exclude="*\.svn*" --include="*\."{mm,m,h,cc,c} \!* *'

{mm,m,h,cc,c} の部分を引用符で囲んではいけません。〜キース

于 2012-04-02T17:33:44.170 に答える
-1

grepからのすべてのバイナリ結果を無視するには

grep -Ri "pattern" * | awk '{if($1 != "Binary") print $0}'

awkの部分は、すべてのバイナリファイルfooが行に一致するものを除外します

于 2010-09-16T18:34:53.810 に答える
-3

これを試して:

  1. --Fcurrdir の下に" " という名前のフォルダを作成します(または、" --F"に名前を変更した別のフォルダをリンクしますdouble-minus-F
  2. #> grep -i --exclude-dir="\-\-F" "pattern" *
于 2010-11-10T23:50:26.257 に答える