Как искать строку в файле PHP с помощью `grep`?

Я ищу объявление класса на сайте с сотнями файлов PHP. Как это сделать в текущей папке и вложенных папках с помощью grep ?

Я тестировал cd ing в папку, а затем что-то вроде

 grep -r 'class MyClass' *.php 

Можешь попробовать

 grep -r --include=*.php "search string" /path/to/dir 

Я бы рекомендовал вам использовать что-то вроде ctags, а не делать это с помощью grep. Однако, если вы хотите, вы можете сделать что-то вроде

  find <top level dir> -name \*.php | xargs grep "class MyClass" 

Это, конечно, предполагает, что у вас есть только одно пространство между class и myClass которое может быть myClass . Легко изменить регулярное выражение, чтобы искать любое количество пробелов.

Если вы используете -r , вы, вероятно, хотите рекурсивно искать только текущий каталог :

 grep -r 'class MyClass' . 

Обратите внимание на период в конце вышесказанного.

То, что вы сказали grep было то, что вы хотели, чтобы он рекурсивно просматривал каждый *.php файл или каталог , но у вас, вероятно, не было каталогов, которые заканчивались расширением .php. Вышеупомянутый – самый простой способ выполнить поиск, но также включает файлы других типов, что особенно проблематично, когда у вас есть каталоги .svn во всем мире. Если у вас не так много других типов файлов, то, как правило, достаточно и хорошо работает.

Большинство воплощений grep не имеют способа указать расширения файлов, которые можно найти, поэтому вы обычно используете find в сочетании с ним:

 find <startDir> -iname '*.php' -exec grep 'class[ \t]*MyClass' {} \; 

-iname сообщает некоторым версиям grep, что вы хотите делать поиск по имени, не -iname от регистра, но многие варианты не GNU-вариантов find не поддерживают его, поэтому вместо него можно использовать -name .

Опция -exec выше имеет побочный эффект вызова grep для каждого файла, что довольно дорого.

Другие версии grep поддерживают a + который сообщает find, чтобы добавить аргументы вместе, чтобы уменьшить количество вызовов исполняемого файла:

 find <startDir> -iname '*.php' -exec grep 'class[ \t]*MyClass' {} + \; 

Часто рекомендуемым способом сокращения вызовов является использование xargs, который будет срабатывать grep как можно меньше, но столько раз, сколько необходимо:

 find <startDir> -iname \*.php | xargs grep "class[ \t]*MyClass" 

xargs достаточно умен, чтобы передать grep до максимального количества аргументов, поддерживаемых в командной строке, но приведенный выше вариант не очень хорошо обрабатывает определенные символы, такие как пробелы. Например, «file.php» filename grep получит «the» в качестве аргумента и «file.php» в качестве аргумента, чтобы оба не были найдены. Вместо этого мы используем:

 find <startDir> -iname \*.php -print0 | xargs -0 grep "class[ \t]*MyClass" 

print0 и -0 работают вместе и используют аргументы, за которыми следует нулевой символ, чтобы аргумент был полностью и однозначно идентифицирован.

Если вы когда-либо имели более одного места после class или вкладку, вы можете разрешить больше символов, изменив регулярное выражение: class[ \t]*MyClass

Это сообщение в StackOverflow содержит другие примеры и демонстрирует, как исключать определенные каталоги, например .svn-каталоги.

Используя все замечательное,

 ack --php 'class MyClass' 
 grep -r 'class MyClass' *.php 

Будет искать по всем папкам с именами, заканчивающимися на .php

 grep -r 'class MyClass' . | grep .php 

Будет искать класс MyClass во всех файлах во всех подпапках, а затем возвращать только те, у которых есть .php.

find . -type f -name *.php -print -exec grep \"class MyClass\" {} \; Предоставит вам содержимое найденной строки, а также путь к файлу.

Если сопоставленные файлы могут иметь произвольные имена, вы должны рассмотреть возможность использования -print0

найти . -type f -name '* .php' -print0 | Xargs -0 grep 'class MyClass'

 grep -rl 'class MyClass' . --include \*.php 

L показывает только имя файла

R – рекурсивный

, Поиск в текущей папке

– включить ограничение имени файла

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

Если есть хотя бы один файл желаемого расширения, вы можете использовать egrep -ir. xargs и xargs демонстрируют свою мощь с помощью одиночных (но очень больших) каталогов, которые grep терпят неудачу и дополнительные квалификаторы (например, если вы хотите искать только файлы .inc, .php и php3). Но он потерял довольно много удобства и скорости в моем опыте. Для деклараций человеческих письменных классов большая проблема будет пустой. Поэтому используйте grep вместо grep. Также LC_ALL = C для дополнительной скорости. Для удобства я часто использую:

LC_ALL=C egrep -irn "class[ ]*myclass([ ]|\n)" * | egrep "\.(inc|php[35]?)"

 -i -- case insensitive -r -- recursive for all file pattern (here *) -n -- include the line number LC_ALL=C -- search in ASCII, not in utf8, this is much faster. [ ]* -- match any number of spaces before the class name ([ ]|\n) -- match a space or newline after the classname 

Это может по-прежнему соответствовать комментариям, например, // class myclass exists in file , но я считаю, что они относительно малы, и их можно отфильтровать с помощью ... | fgrep -v '//' ... | fgrep -v '//'

Вы также можете включить более сложные маски файлов (например, чтобы уловить большинство .inc и .php файлов) в файле egrep, например:

egrep "pattern" *.[ip]*

Это (с первыми вариантами) будет довольно быстрым и в основном ограничено файлами php.

НТН

Я знаю, что это говорит, используя grep , но мой личный фаворит – использовать ack-grep :

 ack-grep "class MyClass" 

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

 ack-grep --type-set php:ext:php "path" 

Пакет имеет множество вариантов; Я бы определенно рекомендовал его (и просматривал связанную с ним справочную страницу) за то, что он придумал.

  • Какие файлы запускаются при входе в систему или перезагрузке моей машины?
  • Как я могу туннелировать весь свой сетевой трафик через SSH?
  • Как я могу заставить мой браузер лгать о моей операционной системе?
  • Есть ли способ полностью удалить Chrome OS на chromebook - и установить Linux (не с двойной загрузкой)
  • Блокировать все порты, кроме SSH / HTTP, в ipchains и iptables
  • Интернет через Ethernet: DNS работает, ping не работает (Windows работает, Linux не работает)
  • Как подключить HDMI-камеру к Linux?
  • Возможно ли установить конкретный каталог на сервере Linux на локальную машину Windows?
  • Создайте пользователя Windows XP из раздела Linux
  • RPM не удалит установленные каталоги, если они были изменены после первоначальной установки
  • Как удалить файл с именем «-p» из bash?
  • Давайте будем гением компьютера.