ファイルシステムのすべてのシェルスクリプトで特定の単語を検索するコマンドラインコマンドが必要だったため、職場で要求して次の解決策を得ました。
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
ここで使用する理由はありません。安全で正しい使用のためには、xargs
GNU専用オプション(find -print0 | xargs -0
)のいくつかの移植性を犠牲にする必要があるということは言うまでもありません。
答え2
非埋め込みLinux、Cygwin、またはその他のシステムGNU grep、存在するFreeBSD、存在するネットワークBSDそしてOSX:
grep -r --include='*.sh' word .
出力を解析しません。ls
。また、出力にfind
次のコマンド置換を使用しないでください。jw013は説明しました。
答え3
grep
find
多くの場合との組み合わせはack
(betterthangrep.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