Řešení 1:
Můžete použít grep:
grep -rn 'classname' /path/to/source
Tím se také vytiskne číslo řádku vedle každé shody.
Nerozlišují se malá a velká písmena:
grep -rin 'classname' /path/to/source
Hledat nerekurzivně ve všech souborech cpp:
grep -n 'classname' /path/to/source/*.cpp
Řešení 2:
Všechny výše uvedené odpovědi budou fungovat perfektně, ale mohou způsobit falešná pozitiva, pokud máte řetězec ve více než jen zdrojovém kódu. Řekněme, že hledáte, kde v projektu Java používáte třídu FooBar, můžete hledat všechny soubory s názvem *.java a grep právě ty.
# grep "FooBar" -Hn $(find -name "*.java")
Část mezi $() se rozšíří na výstup tohoto příkazu. -H vypíše název souboru. Je to výchozí, pokud existuje více než jeden název souboru, ale explicitně jej zde přidáváme pro případ, že rozšíření vrací pouze jeden název souboru. -n vypíše číslo řádku shody.
To bude fungovat pro malé projekty, ale pokud máte co do činění s větším projektem, je zde potenciál pro rozšíření na řetězec delší, než je limit příkazového řádku. Je proto bezpečnější používat:
# find -name "*.java" -print0 | xargs -0 grep "FooBar" -Hn
xargs převezme vstup ze standardu a rozdělí ho tak, aby se vešel na příkazový řádek, a v případě potřeby příkaz spustí vícekrát. Parametry -print0 a -0 jsou vyžadovány pro práci se soubory s mezerami v názvu.
Všechny názvy souborů se shodou můžete také vyhledat pomocí:
# find -name "*.java" -print0 | xargs -0 grep "FooBar" -l
-l pouze zobrazí název souboru a přestane hledat konkrétní soubor, jakmile najde shodu.
Pokud budete podobné věci dělat často, možná se budete chtít podívat na nástroj jako ctags nebo bujné tagy, které udržují vyhledávací index vašeho zdrojového kódu a dokážou rychle odpovědět na tyto druhy otázek. Jak vim, tak emacs mají podporu pro tyto nástroje. Možná byste se také rádi podívali na IDE jako Eclipse, které umí velmi dobře křížové odkazy.
(Vím, že jste hledali definici třídy, ale v Javě bude třída definována v souboru se stejným názvem jako třída. Pokud byste dělali cpp, mohli byste udělat něco jako:
# find -name "*.cpp" -o -name "*.cc" -o -name "*.h" -o -name "*.hpp" -print0 | \
xargs -0 egrep "class\s+FooBar" -Hn
Řešení 3:
Pro hledání ve zdrojovém kódu jsem zjistil, že ack (betterthangrep.com) je, abych citoval marketing, lepší než grep. Jeho výstup je snáze čitelný a spoustu věcí udělá automaticky, jako je ignorování souborů bez zdrojového kódu:adresáře VCS (např. CVS a .svn), záložní soubory.
Řešení 4:
ack je lepší pro vyhledávání zdrojových kódů, protože již rozpoznává některé z nejpopulárnějších přípon souborů (c, perl atd.). Je to stejně rychlé jako grep a ve výchozím nastavení ignoruje všechny vaše artefakty řízení verzí. Pokud například chcete prohledat zdrojový kód vzorového perlu, můžete použít
ack --perl pattern
místo
grep pattern $(find . -name '*.pl' -or -name '*.pm' -or -name '*.pod' | grep -v .svn)