Encuentra archivos que contienen un texto dado

153

En bash, quiero devolver el nombre del archivo (y la ruta al archivo) para cada archivo de tipo que .php|.html|.jscontiene la cadena que no distingue entre mayúsculas y minúsculas"document.cookie" | "setcookie"

¿Como podría hacerlo?

Owen
fuente
44
¿Has considerado simplemente usar grep? cyberciti.biz/faq/grep-in-bash
Terrance
Este título es bastante engañoso. "encontrar-archivos-que-contienen-un-texto-dado"
Josh C

Respuestas:

212
egrep -ir --include=*.{php,html,js} "(document.cookie|setcookie)" .

La rbandera significa buscar de forma recursiva (buscar subdirectorios). La ibandera significa mayúsculas y minúsculas.

Si solo desea nombres de archivo, agregue la bandera l(minúscula L):

egrep -lir --include=*.{php,html,js} "(document.cookie|setcookie)" .
bear24rw
fuente
eso no pareció funcionar para mí (al menos no en Mac) ... simplemente se cuelga ... egrep -lir --include = * "repo" egrep: advertencia: búsqueda recursiva de stdin
Dean Hiller
13
Olvidó agregar la ruta de búsqueda. El camino es '.' en el ejemplo anterior En su caso, el script está esperando que la entrada busque en stdin. Pruebe: egrep -lir --include = * "repo" / (o cualquier otra ruta)
LodeRunner
1
grep -E ... >egrep ...
Aman
Tengo un error grep: (error|fail): No such file or directoryen Ubuntu Desktop 16; alguna pista?
Nam G VU
Para que esto funcione, tuve que omitir * con \. así que tengo--include=\*.{php,html,js}
Mehrad Mahmoudian
53

Intenta algo como grep -r -n -i --include="*.html *.php *.js" searchstrinhere .

lo -ihace insensible a las mayúsculas y minúsculas

el .en los medios del grupo que desea iniciar desde el directorio actual, esto podría ser sustituido con cualquier directorio.

los -rmedios hacen esto de forma recursiva, directamente en el árbol de directorios

la -nimprime el número de línea para los partidos.

le --includepermite agregar nombres de archivo, extensiones. Se aceptan comodines

Para obtener más información, consulte: http://www.gnu.org/software/grep/

Raoul
fuente
44
O tal vez use la -lopción (simplemente imprima los nombres de archivo que coincidan) en lugar de-n
glenn jackman
15

findellos y greppara la cuerda:

Esto encontrará todos los archivos de sus 3 tipos en / starting / path y grep para la expresión regular '(document\.cookie|setcookie)'. Dividir en 2 líneas con la barra invertida solo para facilitar la lectura ...

find /starting/path -type f -name "*.php" -o -name "*.html" -o -name "*.js" | \
 xargs egrep -i '(document\.cookie|setcookie)'
Michael Berkowski
fuente
1
Me gusta el uso universal de find, pero creo que es mejor usarlo-exec grep -l 'sth' {} \;
NGix
Gracias @Michael Berkowski De esta manera más rápido más de 5 u 8 veces # egrep -ir --include=file.foo "(foo|bar)" /diren ~ 500Gb directorio de peso.
Qh0stM4N
9

Suena como un trabajo perfecto para grep o tal vez ack

O esta maravillosa construcción:

find . -type f \( -name *.php -o -name *.html -o -name *.js \) -exec grep "document.cookie\|setcookie" /dev/null {} \;
Fredrik Pihl
fuente
El uso de +1 -exec grep...es mejor que mi xargsmétodo porque no se ahogará con espacios en los nombres de archivo.
Michael Berkowski
@MichaelBerkowski: Se puede utilizar de esta manera para hacer frente a los espacios en blanco en los nombres de archivo: find . -type f -print0 | xargs -0 -I {} grep "search_string" {}. Por supuesto, también se pueden agregar las otras opciones.
Pascal
4
find . -type f -name '*php' -o -name '*js' -o -name '*html' |\
xargs grep -liE 'document\.cookie|setcookie'
nos
fuente
3

Solo para incluir una alternativa más, también puedes usar esto:

find "/starting/path" -type f -regextype posix-extended -regex "^.*\.(php|html|js)$" -exec grep -EH '(document\.cookie|setcookie)' {} \;

Dónde:

  • -regextype posix-extendeddice findqué tipo de expresiones regulares esperar
  • -regex "^.*\.(php|html|js)$"le dice a findla expresión regular que los nombres de archivo deben coincidir
  • -exec grep -EH '(document\.cookie|setcookie)' {} \;le indica findque ejecute el comando (con sus opciones y argumentos) especificado entre la -execopción y el \;archivo para cada archivo que encuentre, donde {}representa dónde va la ruta del archivo en este comando.

    mientras

    • E la opción dice grep que use expresiones regulares extendidas (para admitir los paréntesis) y ...
    • Hla opción le dice grepque imprima las rutas de los archivos antes de las coincidencias.

Y, dado esto, si solo desea rutas de archivos, puede usar:

find "/starting/path" -type f -regextype posix-extended -regex "^.*\.(php|html|js)$" -exec grep -EH '(document\.cookie|setcookie)' {} \; | sed -r 's/(^.*):.*$/\1/' | sort -u

Dónde

  • |[pipe] envía la salida del findsiguiente comando después de esto (que es sed, entonces sort)
  • rLa opción le dice sedque use expresiones regulares extendidas.
  • s/HI/BYE/le dice sedque reemplace cada Primera aparición (por línea) de "HI" con "BYE" y ...
  • s/(^.*):.*$/\1/le dice que reemplace la expresión regular (^.*):.*$(es decir, un grupo [cosas encerradas por ()] incluyendo todo [ .*= uno o más de cualquier carácter] desde el comienzo de la línea [ ^] hasta 'el primero': 'seguido de cualquier cosa hasta' el final de línea [ $]) por el primer grupo [\1 ] de la expresión regular reemplazada.
  • ule dice a sort que elimine las entradas duplicadas (tome sort -ucomo opcional).

... LEJOS de ser la forma más elegante. Como dije, mi intención es aumentar el rango de posibilidades (y también dar explicaciones más completas sobre algunas herramientas que podría usar).

Pedro Vernetti
fuente