解決策 1:
grep を使用できます:
grep -rn 'classname' /path/to/source
これにより、各一致の横に行番号も表示されます。
大文字と小文字を区別しない:
grep -rin 'classname' /path/to/source
すべての cpp ファイルを非再帰的に検索:
grep -n 'classname' /path/to/source/*.cpp
解決策 2:
上記の回答はすべて問題なく機能しますが、ソース コード以外に文字列がある場合は、誤検知が発生する可能性があります。 Java プロジェクトで FooBar クラスを使用する場所を探しているとします。*.java という名前のすべてのファイルを検索し、それらだけを grep できます。
# grep "FooBar" -Hn $(find -name "*.java")
$() の間のセクションは、そのコマンドの出力に展開されます。 -H はファイル名を出力します。これは、複数のファイル名がある場合のデフォルトですが、展開によって 1 つのファイル名しか返されない場合に備えて、ここに明示的に追加します。 -n は一致した行番号を出力します。
これは小規模なプロジェクトでは機能しますが、大規模なプロジェクトを扱っている場合は、検索がコマンド ラインの制限よりも長い文字列に拡張される可能性があります。したがって、使用する方が安全です:
# find -name "*.java" -print0 | xargs -0 grep "FooBar" -Hn
xargs は、標準入力から入力を受け取り、それを分割してコマンドラインに収まるようにし、必要に応じてコマンドを複数回実行します。名前にスペースが含まれるファイルを処理するには、-print0 と -0 が必要です。
以下を使用して、一致するすべてのファイル名を探すこともできます:
# find -name "*.java" -print0 | xargs -0 grep "FooBar" -l
-l はファイル名を表示するだけで、一致するファイルが見つかるとすぐに特定のファイルの検索を停止します。
この種のことを頻繁に行う場合は、ソース コードの検索インデックスを維持し、これらの種類の質問にすばやく答えることができる ctags や exuberant tags などのツールを検討することをお勧めします。 vim と emacs の両方がこれらのツールをサポートしています。また、相互参照を非常にうまく行うことができる eclipse のような IDE を見たいと思うかもしれません。
(あなたがクラス定義を探していたことは知っていますが、Java では、クラスはクラスと同じ名前のファイルで定義されます。cpp を実行している場合は、次のようにすることができます:
# find -name "*.cpp" -o -name "*.cc" -o -name "*.h" -o -name "*.hpp" -print0 | \
xargs -0 egrep "class\s+FooBar" -Hn
解決策 3:
ソース コードを検索すると、マーケティングを引用すると、ack (betterthangrep.com) が grep より優れていることがわかりました。その出力は読みやすく、VCS ディレクトリ (CVS や .svn など)、バックアップ ファイルなど、ソース コード以外のファイルを無視するなど、多くのことを自動的に行います。
解決策 4:
ack は、最も一般的なファイル拡張子 (c、perl など) の一部を既に認識しているため、ソース コードの検索に適しています。これは grep と同じくらい高速で、デフォルトではすべてのバージョン管理アーティファクトを無視します。たとえば、あるパターンの perl ソース コードを検索したい場合に使用できます
ack --perl pattern
の代わりに
grep pattern $(find . -name '*.pl' -or -name '*.pm' -or -name '*.pod' | grep -v .svn)