El uso de xargs en las respuestas anteriores no es necesario; puedes lograr lo mismo así:
find . -type f -exec grep -q <string-to-match> {} \; -not -exec grep -q <string-not-to-match> {} \; -print
grep -q
significa ejecutar silenciosamente pero devuelve un código de salida que indica si se encontró una coincidencia; find
luego puede usar ese código de salida para determinar si debe seguir ejecutando el resto de sus opciones. Si -exec grep -q <string-to-match> {} \;
devuelve 0, luego pasará a ejecutar -not -exec grep -q <string-not-to-match>{} \;
. Si eso también devuelve 0, continuará ejecutando -print
, que imprime el nombre del archivo.
Como ha señalado otra respuesta, usando find
de esta manera tiene grandes ventajas sobre grep -Rl
donde solo desea buscar archivos de un tipo determinado. Si, por el contrario, realmente desea buscar en todos los archivos, grep -Rl
es probablemente más rápido, ya que usa un grep
proceso para realizar el primer filtro para todos los archivos, en lugar de un grep
separado proceso para cada archivo.
Prueba esto:
grep -rl <string-to-match> | xargs grep -L <string-not-to-match>
Explicación:grep -lr
hace que grep genere recursivamente (r) una lista (l) de todos los archivos que contienen <string-to-match>
. xargs recorre estos archivos, llamando a grep -L
sobre cada uno de ellos. grep -L
solo generará el nombre del archivo cuando el archivo no contenga <string-not-to-match>
.
Estas respuestas parecen estar fuera de lugar como la coincidencia AMBAS instrumentos de cuerda. El siguiente comando debería funcionar mejor:
grep -l <string-to-match> * | xargs grep -c <string-not-to-match> | grep '\:0'