Quiero encontrar archivos que contengan dos cadenas juntas, por ejemplo, el archivo contiene ambos string1y string2.
Quiero la ruta completa de los archivos en la salida. No quiero ver advertencias de "permiso denegado".
grep -l string2 `grep -l string1 /path/*`
que es lo mismo que
grep -l string2 $(grep -l string1 /path/*)
Editar: heres por qué grep string1 /path/* | grep string2no hace lo que creo que alwbtc quiere.
$ cd /tmp
$ cat a
apples
oranges
bananas
$ cat b
apples
mangoes
lemons
$ cat c
mangoes
limes
pears
$ cd ~
$ grep apples /tmp/* | grep mangoes
$
No se encontró nada, pero el archivo b contiene ambas cadenas.
Esto es lo que creo que alwbtc quiere
$ grep -l apples $(grep -l mangoes /tmp/*)
/tmp/b
-lopción de devolver los nombres de los archivos en lugar de las líneas. Luego usa el signo de dólar o las comillas inversas para pasar esa lista comoFILEargumento al segundo grep. Esto permite que el segundo grep busque la totalidad de cada archivo encontrado en lugar de las líneas individuales como en mi solución.-lopción para que ambos comandos se consideren iguales.Tubería una
grepen otra:grep "string1" /path/to/files/* | grep "string2"fuente
Aquí está el comando ack equivalente a la respuesta de RedGrittyBrick :
Funciona de la misma manera (excepto
ackpor defecto busca el directorio actual de forma recursiva). El contenido dentro de las$()búsquedasstring1pero-lsolo genera los nombres de archivo donde se encontró esa cadena. Luego se pasan como argumentos al comando externo, lo que significa que solostring2se busca dentro de esa lista de archivos.fuente
o menos redundante:
Esto funcionará si las cadenas están en diferentes líneas del mismo archivo y también evitará falsos positivos si un nombre de archivo contiene una de las cadenas.
fuente
Para profundizar en la solución de @ RedGrittyBrick que tiene una deficiencia al ejecutar el comando desatendido más para suprimir la salida de error según lo previsto y encontrar archivos de forma recursiva, puede considerar
grep -l 'STRING1' $(! grep -lrs 'STRING2' /absolute/path/to/search/dir && echo /dev/null)-sLa opción suprimirá los mensajes de error. La-ropción permite buscar cadenas en directorios anidados arbitrariamente!combinados con&& echo /dev/nullgarantías de que el comando no colgará. De lo contrario, siinner grepno encuentra ningún archivo, no generará nada, por lo queouter grepesperará indefinidamente la entrada para buscar. Este salidas solución/dev/nullen estos casos por lo queouter grepvan a buscarSTRING1en/dev/nulldonde se supone que no encontrar nada.fuente
Estaba buscando una forma extensible de hacer 2 o más cadenas y se me ocurrió esto:
La primera grep encuentra de forma recursiva los nombres de los archivos que contienen
string1dentropath-to-files.Los resultados se canalizan a los
xargsque ejecuta uno o más comandos grep en esos archivosstring2.Los resultados se canalizan a otro
xargscomando parastring3: es el mismo que la primeraxargsllamada, pero busca una cadena diferente.El uso de
xargsevitará problemas cuando haya tantos resultados que la línea de comando resultante del uso de ticks de retroceso sea demasiado larga.Para evitar las advertencias podemos redirigir
stderra/dev/null:No es necesario en las siguientes llamadas grep porque
string1ya se ha encontrado dentro del archivo, por lo que se sabe que los permisos son buenos.fuente