特定のファイル形式で単語​​を検索する再帰 grep

特定のファイル形式で単語​​を検索する再帰 grep

ファイルシステムのすべてのシェルスクリプトで特定の単語を検索するコマンドラインコマンドが必要だったため、職場で要求して次の解決策を得ました。

grep word `find / -name \*.sh 2>/dev/null`
find / -name "*.sh" 2>/dev/null | xargs grep word

しかし、私はコマンドラインに慣れていないので、両方のソリューションは透明に見えません。私は次の作業を好みます。

ls -r *.sh | cat | grep -H word

しかし、ファイル名をcatにパイプすることはできないようです(少なくともそれが問題だと思います)。

最も明確な解決策は何ですか?第二に、最も効率的なソリューションは何ですか?

編集:スクリプトを変更できるように、どのファイルに単語が見つかったかを知る必要があります。

答え1

編集する:GNUユーティリティがある場合は、次を参照してください。ザイルズの答えgrepこれよりもGNUの再帰機能を使用するより簡単な方法がありますfind。ファイル名のみを表示するには、-l以下に説明するオプションを追加する必要があります。


grep -l word一致するファイルの名前のみを印刷するために使用されます。

ファイル.shシステムから/find

最も移植可能で効果的なアドバイスは次のとおりです。

find / -type f -name '*.sh' -exec grep -l word {} + 2>/dev/null

各コンポーネントの意味を理解すると、ほとんど読みやすく、解析は難しくありません。

  • find /findファイルシステムのルートディレクトリで実行します。/
  • -type f:通常のファイルのみが一致します。
  • -name '*.sh':...そして名前が終わるファイルだけが一致します。.sh
  • -exec ... {} +...処置: グループ内の一致するファイルに対して指定したコマンドを実行し、{}グループのファイル名に置き換えます。アイデアは、system()の制限内で一度に多くのファイルに対してコマンドを実行することですARG_MAX。フォームの効率は、各呼び出しに渡されるファイルの数を最大化して、コマンドを呼び出す必要がある回数を最小限に抑えること{} +から来ます。......
  • grep -l word {}:ここで上記の{}ように繰り返し{}、ファイル名に置き換えられます。前述のように、grep -l印刷にはword
  • 2>/dev/null:エラーメッセージを隠します(技術的には標準エラーをブラックホールにリダイレクト/dev/null)。これは審美的で実用的な理由によるものです。これを実行すると、多くの「権限の拒否」メッセージが表示され、find読み取り権限のないファイルとナビゲーション権限のないディレクトリについて気にしない可能性があるためです。/

あなたが質問に投稿したアドバイスにはいくつかの問題があります。両方

grep word `find / -name \*.sh 2>/dev/null

そして

find / -name "*.sh" 2>/dev/null | xargs grep word

名前にスペースが含まれるファイルは失敗します。ファイル名全体をコマンド置換に含めないことをお勧めします。 1つ目は、ARG_MAXの制限に関して追加の問題が発生する可能性があります。 2番目は私の提案に近いですが、xargsここで使用する理由はありません。安全で正しい使用のためには、xargsGNU専用オプション(find -print0 | xargs -0)のいくつかの移植性を犠牲にする必要があるということは言うまでもありません。

答え2

非埋め込みLinux、Cygwin、またはその他のシステムGNU grep、存在するFreeBSD、存在するネットワークBSDそしてOSX:

grep -r --include='*.sh' word .

出力を解析しません。ls。また、出力にfind次のコマンド置換を使用しないでください。jw013は説明しました

答え3

grepfind多くの場合との組み合わせはackbetterthangrep.com):

ack [OPTION]... PATTERN [FILE]

あなたの例では、

ack --shell word /

ノート

ack

  • 再帰的に検索しますが(基本的に)
  • .git、、.hg....svnなどの一般的なバージョン管理システムの(デフォルト)ディレクトリを無視します。
  • 一般的なファイル形式のフィルタを使用して結果の範囲を簡単に絞り込むことができます(さまざまなファイル名パターンについては以下を参照)。
  • 「大文字と小文字を無視する」などgrepの同様の構文と同じ/類似パラメータがあります。-i
  • ack-grepシステムから呼び出すことができます(私の記憶が正しい場合はDebianベースのディストリビューションから)。

ファイル名パターン

このオプションは--shell省略されており、次のようないくつかの--type=shellファイル形式を扱います。.sh .bash .csh .tcsh .ksh .zsh

ack --help-types

ファイルのみが必要な場合は、.sh一意の型を定義(追加)し、次のようにshこのフィルタ()を使用する必要があります。--sh

ack word --type-add=sh=.sh --sh /

やや複雑に見えますが、.sh以下のファイルを再帰的に検索できます/。ローカル検索の場合(たとえば、開始ディレクトリを指定せずに\)、より簡単になります。

ack word *.sh

関連情報