Quiero encontrar archivos que contengan dos cadenas juntas, por ejemplo, el archivo contiene ambos string1
y 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 string2
no 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
-l
opció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 comoFILE
argumento 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.-l
opción para que ambos comandos se consideren iguales.Tubería una
grep
en 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
ack
por defecto busca el directorio actual de forma recursiva). El contenido dentro de las$()
búsquedasstring1
pero-l
solo genera los nombres de archivo donde se encontró esa cadena. Luego se pasan como argumentos al comando externo, lo que significa que solostring2
se 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)
-s
La opción suprimirá los mensajes de error. La-r
opción permite buscar cadenas en directorios anidados arbitrariamente!
combinados con&& echo /dev/null
garantías de que el comando no colgará. De lo contrario, siinner grep
no encuentra ningún archivo, no generará nada, por lo queouter grep
esperará indefinidamente la entrada para buscar. Este salidas solución/dev/null
en estos casos por lo queouter grep
van a buscarSTRING1
en/dev/null
donde 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
string1
dentropath-to-files
.Los resultados se canalizan a los
xargs
que ejecuta uno o más comandos grep en esos archivosstring2
.Los resultados se canalizan a otro
xargs
comando parastring3
: es el mismo que la primeraxargs
llamada, pero busca una cadena diferente.El uso de
xargs
evitará 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
stderr
a/dev/null
:No es necesario en las siguientes llamadas grep porque
string1
ya se ha encontrado dentro del archivo, por lo que se sabe que los permisos son buenos.fuente