Con herramientas GNU:
find . -type f -exec grep -lZ FIND {} + | xargs -r0 grep -l ME
Puedes hacer de manera estándar:
find . -type f -exec grep -q FIND {} \; -exec grep -l ME {} \;
Pero eso ejecutaría dos greps por archivo. Para evitar ejecutar tantos grepcorreos electrónicos y seguir siendo portátil mientras se permite cualquier carácter en los nombres de archivo, puede hacer lo siguiente:
convert_to_xargs() {
sed "s/[[:blank:]\"\']/\\\\&/g" | awk '
{
if (NR > 1) {
printf "%s", line
if (!index($0, "//")) printf "\\"
print ""
}
line = $0
}'
END { print line }'
}
find .//. -type f |
convert_to_xargs |
xargs grep -l FIND |
convert_to_xargs |
xargs grep -l ME
La idea es convertir la salida de finda un formato adecuado para xargs (que espera un espacio en blanco (SPC / TAB / NL, y los otros espacios en blanco de su configuración regional con algunas implementaciones de xargs) lista separada de palabras donde las comillas simples, dobles y barras invertidas pueden escapar espacios en blanco y entre sí).
En general, no puede procesar la salida de find -print, ya que separa los nombres de archivo con un carácter de nueva línea y no escapa a los caracteres de nueva línea que se encuentran en los nombres de archivo. Por ejemplo si vemos:
./a
./b
No tenemos forma de saber si se trata de un archivo llamado ben un directorio llamado a<NL>.o si son los dos archivos ay b.
Al usar .//., porque //no puede aparecer de otra manera en una ruta de archivo como resultado find(porque no existe un directorio con un nombre vacío y /no está permitido en un nombre de archivo), sabemos que si vemos una línea que contiene //, entonces eso es la primera línea de un nuevo nombre de archivo. Entonces podemos usar ese awkcomando para escapar de todos los caracteres de nueva línea, pero aquellos que preceden a esas líneas.
Si tomamos el ejemplo anterior, findsaldría en el primer caso (un archivo):
.//a
./b
Que awk escapa a:
.//a\
./b
Entonces eso lo xargsve como un argumento. Y en el segundo caso (dos archivos):
.//a
.//b
Lo awkque dejaría como está, así que xargsve dos argumentos.