Как мне искать файлы, некоторые из которых могут быть каталогами (в данном случае рекурсивно) для данной строки?
Я хотел бы найти в исходных файлах определение класса, поэтому было бы здорово, если бы перед каждой выходной строкой было имя содержащего файла.
Вы можете использовать grep:
grep -rn 'classname' /path/to/source
Это также напечатает номер строки рядом с каждым совпадением.
Без учета регистра:
grep -rin 'classname' /path/to/source
Нерекурсивный поиск во всех файлах cpp:
grep -n 'classname' /path/to/source/*.cpp
Все приведенные выше ответы будут работать отлично, но могут вызвать ложные срабатывания, если у вас есть строка не только в исходном коде. Допустим, вы ищете место, где вы используете класс FooBar в java-проекте, вы можете искать все файлы с именами * .java и grep только в них.
# grep "FooBar" -Hn $(find -name "*.java")
Раздел между $ () расширится до вывода этой команды. -H выводит имя файла. По умолчанию используется более одного имени файла, но мы явно добавляем его сюда на тот случай, если расширение возвращает только одно имя файла. -N печатает номер строки совпадения.
Это будет работать для небольших проектов, но если вы имеете дело с более крупным проектом, есть вероятность, что находка расширится до строки, превышающей ограничение командной строки. Поэтому безопаснее использовать:
# find -name "*.java" -print0 | xargs -0 grep "FooBar" -Hn
xargs будет принимать входные данные из стандартного и разделять их так, чтобы они помещались в командной строке, при необходимости выполняя команду несколько раз. -Print0 и -0 необходимы для работы с файлами, в имени которых есть пробелы.
Вы также можете найти все совпадающие имена файлов, используя:
# find -name "*.java" -print0 | xargs -0 grep "FooBar" -l
-L просто отобразит имя файла и перестанет искать в конкретном файле, как только найдет совпадение.
Если вы собираетесь делать подобные вещи часто, вы можете взглянуть на такой инструмент, как ctags или обильные теги, которые поддерживают поисковый индекс вашего исходного кода и могут быстро ответить на подобные вопросы. И vim, и emacs поддерживают эти инструменты. Вы также можете взглянуть на IDE, такую как eclipse, которая очень хорошо справляется с перекрестными ссылками.
(Я знаю, что вы искали определение класса, но в Java класс будет определен в файле с тем же именем, что и класс. Если вы выполняли cpp, вы могли бы сделать что-то вроде:
# find -name "*.cpp" -o -name "*.cc" -o -name "*.h" -o -name "*.hpp" -print0 | \
xargs -0 egrep "class\s+FooBar" -Hn
Для поиска в исходном коде я обнаружил, что ack (betterthangrep.com), если цитировать маркетинг, лучше, чем grep. Его вывод легче читать, и он будет делать много вещей автоматически, например, игнорировать файлы, не являющиеся исходными кодами: каталоги VCS (например, CVS и .svn), файлы резервных копий.
подтверждать лучше подходит для поиска в исходных кодах, так как он уже распознает некоторые из самых популярных расширений файлов (c, perl и т. д.). Он работает так же быстро, как grep, и по умолчанию игнорирует все ваши артефакты управления версиями. Например, если вы хотите найти какой-либо шаблон в исходном коде Perl, вы можете использовать
ack --perl pattern
вместо того
grep pattern $(find . -name '*.pl' -or -name '*.pm' -or -name '*.pod' | grep -v .svn)
grep -r string *
рекурсивно находит все файлы, содержащие символы «строка» во всех (не скрытых) файлах в текущем каталоге и во всех подкаталогах. Вы можете использовать обычные регулярные выражения для настройки строки. Дополнительные параметры см. На страницах grep info / man.
Уже ответил (я думаю, что это то, что вы ищете) на этот пост serverfault:
Рекурсивный текстовый поиск с помощью grep и шаблонов файлов
я часто использую это, поэтому я добавил две функции bash в свой .bashrc
Сначала выполняется рекурсивный поиск текст в именах файлов.
Второй будет выполнять рекурсивный поиск текст внутри файлов, возвращающих имена файлов, которые совпадают.
ff () {
find . -name "*$@*" -print;
}
fff () {
find . -type f -print0 | xargs -0 grep -l $@
}
пример использования:
[lunix@godzilla ~/tmp]$ ff foo
./slideshow/foo
./slideshow/velocity_puppet_workshop_2009/repo/modules/foo
[lunix@godzilla ~/tmp/test]$ fff commodo
./file2
[lunix@godzilla ~/tmp/test]$ ll
total 16K
drwxr-xr-x 2 lunix lunix 4.0K 2009-06-29 23:01 .
drwxr-xr-x 4 lunix lunix 4.0K 2009-06-29 22:57 ..
-rw-r--r-- 1 lunix lunix 1.3K 2009-06-29 22:59 file1
-rw-r--r-- 1 lunix lunix 1.7K 2009-06-29 23:00 file2
Этот классический find + exec тоже может пригодиться:
find /path/to/ -type f -exec grep -i 'string' {} \;
Попробуйте команду:
grep -rn *
Это сработает !!