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 grep
correos 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 find
a 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 b
en un directorio llamado a<NL>.
o si son los dos archivos a
y 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 awk
comando para escapar de todos los caracteres de nueva línea, pero aquellos que preceden a esas líneas.
Si tomamos el ejemplo anterior, find
saldría en el primer caso (un archivo):
.//a
./b
Que awk escapa a:
.//a\
./b
Entonces eso lo xargs
ve como un argumento. Y en el segundo caso (dos archivos):
.//a
.//b
Lo awk
que dejaría como está, así que xargs
ve dos argumentos.