Вопрос: Поиск нескольких файлов для строки в LInux


Как искать файлы, некоторые из которых могут быть каталоги (в данном случае рекурсивно) для данной строки?

Я хотел бы искать исходные файлы для определения класса, поэтому было бы замечательно, если бы имя каждого файла содержалось перед каждой выходной строкой.


5
2018-06-29 10:05


Источник


Могу ли я спросить, зачем вам это нужно? - Anonymous
Я ищу исходные файлы для определения метода. - Alex


Ответы:


Вы можете использовать grep:

grep -rn 'classname' /path/to/source

Это также напечатает номер строки рядом с каждым совпадением.

Без учета регистра:

grep -rin 'classname' /path/to/source

Поиск не рекурсивно во всех файлах cpp:

grep -n 'classname' /path/to/source/*.cpp

8
2018-06-29 10:08





Все приведенные выше ответы будут работать отлично, но могут вызывать ложные срабатывания, если у вас есть строка больше, чем только исходный код. Предположим, что вы ищете, где вы используете класс 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 

4
2018-06-29 11:17



Очень полный ответ. - nickd


Для поиска по исходному коду я нашел, что ack (betterthangrep.com), чтобы процитировать маркетинг, лучше, чем grep. Его вывод легче читать, и он будет делать много вещей автоматически, например, игнорировать файлы, не являющиеся исходными кодами: каталоги VCS (например, CVS и .svn), файлы резервных копий.


2
2018-06-29 10:26





извед лучше искать исходники, поскольку он уже распознает некоторые из самых популярных расширений файлов (c, perl и т. д.). Это так же быстро, как grep, и по умолчанию игнорирует весь артефакт управления версиями. Например, если вы хотите найти какой-либо исходный код perl шаблона, вы можете использовать

ack --perl pattern

вместо

grep pattern $(find . -name '*.pl' -or -name '*.pm' -or -name '*.pod' | grep -v .svn)

2
2017-07-02 04:07





grep -r string *

находит все файлы, содержащие символы «строка» во всех (не скрытых) файлах в текущем каталоге и во всех подкаталогах рекурсивно. Вы можете использовать обычные регулярные выражения для настройки строки. Дополнительные сведения см. На страницах grep info / man.


0
2018-06-29 10:12





Уже ответили (я думаю, это то, что вы ищете) на этой странице serverfault:

Рекурсивный поиск текста с использованием шаблонов grep и файлов


0
2018-06-29 11:21





это то, что я нахожу себе, используя много, поэтому я поставил две функции 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

0
2018-06-29 13:00





Эта классическая находка + exec также может быть удобной:

find /path/to/ -type f -exec grep -i 'string' {} \;

0
2017-09-23 19:16





grep -rn * это сработает !!


-1
2018-06-29 10:18



Почему вы кричите? - Telemachus