¿Cómo busco una cadena en un archivo PHP usando `grep`?
11
Estoy buscando una declaración de clase en un sitio con cientos de archivos PHP. ¿Cómo puedo hacer esto en la carpeta y subcarpetas actuales usando grep ?
Cuando esto migra a superusuario, es posible que desee decir algo sobre lo que quería que grep -rno le dio.
Estoy confundido, ¿no te respondiste? ¿Cuáles fueron los resultados de esa línea? ¿Estás tratando de optimizarlo aún más? imagina leer esta pregunta como alguien más, porque es confusa y poco clara.
meder omuraliev
@otros comentarios: Su declaración grep -r no está dando lo que quiere, a menos que todas las carpetas terminen con .php, lo cual probablemente no sea el caso ...
David Oneill
No obtuve nada en absoluto. Supongo que no funcionó porque sé que lo encuentra cuando estoy en la carpeta que tiene el archivo con esta clase
Encontré el archivo por suerte. Cuando busca el archivo en la carpeta que tiene el archivo PHP con esa línea, lo encuentra (no necesita -r). Si hago un CD en la raíz y hago la búsqueda con recursión -r, no devuelve nada.
Por supuesto, esto supone que tiene un solo espacio entre classy myClassque podría no ser cierto. Sin embargo, es fácil cambiar la expresión regular para buscar cualquier cantidad de espacios en blanco.
Si usa -r, probablemente desee buscar recursivamente solo el directorio actual :
grep -r 'class MyClass' .
Tenga en cuenta el período al final de lo anterior.
Lo que dijo grepfue que quería que buscara recursivamente cada *.phparchivo o directorio , pero que probablemente no tenía ningún directorio que terminara en una extensión .php. Lo anterior es la forma más simple posible de hacer la búsqueda, pero también incluye archivos de otros tipos, lo cual es especialmente problemático cuando tiene directorios .svn en todas partes. Si no tiene muchos otros tipos de archivos, lo anterior es generalmente suficiente y funciona bien.
La mayoría de las encarnaciones de grep no tienen una forma de especificar las extensiones de archivo que se pueden buscar, por lo que generalmente usa find junto con él:
-inamele dice a algunas versiones de grep que desea hacer una búsqueda de nombre de archivo que no distingue entre mayúsculas y minúsculas, pero muchas de las variantes de find que no son GNU no lo admiten, por lo que podría usarlo -nameen su lugar.
La -execopción anterior tiene el efecto secundario de invocar grep para cada archivo, lo cual es bastante costoso.
Aún otras versiones de grep soportan a +que le dice a find que agregue los argumentos juntos para reducir el número de invocaciones del ejecutable:
Una forma frecuentemente recomendada de reducir las invocaciones es usar xargs que dispararán grep tan pocas como sea posible, pero tantas veces como sea necesario:
xargses lo suficientemente inteligente como para pasar grep hasta el número máximo de argumentos admitidos en la línea de comando, pero la variación anterior no maneja muy bien ciertos caracteres como espacios. Por ejemplo, si 'el archivo.php' un nombre de archivo grep recibiría 'el' como argumento y 'archivo.php' como argumento para que no se encuentren ambos. En su lugar usamos:
print0y -0trabajen juntos y usen argumentos seguidos de un carácter nulo para que el argumento se identifique completa e inequívocamente.
Si alguna vez tiene más de un espacio después class, o una pestaña, es posible que desee permitir más caracteres cambiando la expresión regular:class[ \t]*MyClass
Esta publicación en StackOverflow tiene otros ejemplos y muestra cómo excluir ciertos directorios, como los directorios .svn.
find . -type f -name *.php -print -exec grep \"class MyClass\" {} \; le dará el contenido de la línea en la que se encuentra, así como la ruta al archivo.
Probablemente desee insensibilidad a mayúsculas y tolerancia de espacios en blanco, y grep terminará si no encuentra ninguna instancia del patrón de archivo deseado en el directorio actual. Necesita saber por dónde empezar, por así decirlo, y ningún archivo coincidente no produce una ruta de inicio.
Si hay al menos un archivo de la extensión deseada, puede usar egrep -ir. findy xargsmuestra su poder con directorios planos (pero muy grandes) en los que grep falla y calificadores adicionales (por ejemplo, si desea buscar solo archivos .inc, .php y php3). Pero pierde bastante comodidad y velocidad en mi experiencia. Para las declaraciones de clases escritas en humanos, un gran problema será el espacio en blanco. Así que usa egrep en lugar de grep. También LC_ALL = C para velocidad extra. Por conveniencia, a menudo uso:
-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
Esto todavía puede coincidir con los comentarios, como // class myclass exists in file, pero creo que son pequeños relativamente, y se pueden filtrar con... | fgrep -v '//'
También puede incluir máscaras de archivos más complejas (por ejemplo, para capturar la mayoría de los archivos .inc y .php) en el patrón de archivo egrep de la siguiente manera:
egrep "pattern" *.[ip]*
Eso (con las primeras opciones) será bastante rápido y se limitará principalmente a los archivos php.
Sé que dice usar grep, pero mi favorito personal es usar ack-grep:
ack-grep "class MyClass"
Esto se ejecuta de forma recursiva, enumera el nombre del archivo en el que encuentra resultados, con números de línea para el lugar donde se encuentran, y resalta. Para apuntar específicamente a archivos php que puede ejecutar:
ack-grep --type-set php:ext:php "path"
El paquete tiene una gran cantidad de opciones; Definitivamente lo recomendaría (y navegar por su página man asociada) para hacer cosas elegantes.
grep -r
no le dio.Respuestas:
Puedes probar
fuente
Recomiendo que uses algo como ctags en lugar de hacerlo con grep. Sin embargo, si quieres, puedes hacer algo como
Por supuesto, esto supone que tiene un solo espacio entre
class
ymyClass
que podría no ser cierto. Sin embargo, es fácil cambiar la expresión regular para buscar cualquier cantidad de espacios en blanco.fuente
Si usa
-r
, probablemente desee buscar recursivamente solo el directorio actual :Tenga en cuenta el período al final de lo anterior.
Lo que dijo
grep
fue que quería que buscara recursivamente cada*.php
archivo o directorio , pero que probablemente no tenía ningún directorio que terminara en una extensión .php. Lo anterior es la forma más simple posible de hacer la búsqueda, pero también incluye archivos de otros tipos, lo cual es especialmente problemático cuando tiene directorios .svn en todas partes. Si no tiene muchos otros tipos de archivos, lo anterior es generalmente suficiente y funciona bien.La mayoría de las encarnaciones de grep no tienen una forma de especificar las extensiones de archivo que se pueden buscar, por lo que generalmente usa find junto con él:
-iname
le dice a algunas versiones de grep que desea hacer una búsqueda de nombre de archivo que no distingue entre mayúsculas y minúsculas, pero muchas de las variantes de find que no son GNU no lo admiten, por lo que podría usarlo-name
en su lugar.La
-exec
opción anterior tiene el efecto secundario de invocar grep para cada archivo, lo cual es bastante costoso.Aún otras versiones de grep soportan a
+
que le dice a find que agregue los argumentos juntos para reducir el número de invocaciones del ejecutable:Una forma frecuentemente recomendada de reducir las invocaciones es usar xargs que dispararán grep tan pocas como sea posible, pero tantas veces como sea necesario:
xargs
es lo suficientemente inteligente como para pasar grep hasta el número máximo de argumentos admitidos en la línea de comando, pero la variación anterior no maneja muy bien ciertos caracteres como espacios. Por ejemplo, si 'el archivo.php' un nombre de archivo grep recibiría 'el' como argumento y 'archivo.php' como argumento para que no se encuentren ambos. En su lugar usamos:print0
y-0
trabajen juntos y usen argumentos seguidos de un carácter nulo para que el argumento se identifique completa e inequívocamente.Si alguna vez tiene más de un espacio después
class
, o una pestaña, es posible que desee permitir más caracteres cambiando la expresión regular:class[ \t]*MyClass
Esta publicación en StackOverflow tiene otros ejemplos y muestra cómo excluir ciertos directorios, como los directorios .svn.
fuente
Usando el ack siempre maravilloso ,
fuente
buscará en todas las carpetas con nombres que terminen en .php
buscará la clase MyClass en todos los archivos en todas las subcarpetas, luego solo devolverá los que tengan .php en ellos.
fuente
find . -type f -name *.php -print -exec grep \"class MyClass\" {} \;
le dará el contenido de la línea en la que se encuentra, así como la ruta al archivo.fuente
En caso de que los archivos coincidentes puedan tener nombres arbitrarios, debería considerar usar
-print0
fuente
l solo muestra el nombre del archivo
r es recurrente
. busca en la carpeta actual
--incluir límites de extensión de nombre de archivo
fuente
Probablemente desee insensibilidad a mayúsculas y tolerancia de espacios en blanco, y grep terminará si no encuentra ninguna instancia del patrón de archivo deseado en el directorio actual. Necesita saber por dónde empezar, por así decirlo, y ningún archivo coincidente no produce una ruta de inicio.
Si hay al menos un archivo de la extensión deseada, puede usar egrep -ir.
find
yxargs
muestra su poder con directorios planos (pero muy grandes) en los que grep falla y calificadores adicionales (por ejemplo, si desea buscar solo archivos .inc, .php y php3). Pero pierde bastante comodidad y velocidad en mi experiencia. Para las declaraciones de clases escritas en humanos, un gran problema será el espacio en blanco. Así que usa egrep en lugar de grep. También LC_ALL = C para velocidad extra. Por conveniencia, a menudo uso:LC_ALL=C egrep -irn "class[ ]*myclass([ ]|\n)" * | egrep "\.(inc|php[35]?)"
Esto todavía puede coincidir con los comentarios, como
// class myclass exists in file
, pero creo que son pequeños relativamente, y se pueden filtrar con... | fgrep -v '//'
También puede incluir máscaras de archivos más complejas (por ejemplo, para capturar la mayoría de los archivos .inc y .php) en el patrón de archivo egrep de la siguiente manera:
egrep "pattern" *.[ip]*
Eso (con las primeras opciones) será bastante rápido y se limitará principalmente a los archivos php.
HTH
fuente
Sé que dice usar
grep
, pero mi favorito personal es usarack-grep
:Esto se ejecuta de forma recursiva, enumera el nombre del archivo en el que encuentra resultados, con números de línea para el lugar donde se encuentran, y resalta. Para apuntar específicamente a archivos php que puede ejecutar:
El paquete tiene una gran cantidad de opciones; Definitivamente lo recomendaría (y navegar por su página man asociada) para hacer cosas elegantes.
fuente