bash - sintaxis - nombre de usuario con espacio
encontrar con espacios en nombre de archivo (4)
A menudo uso grep dos veces con find para buscar dos patrones en un archivo de la siguiente manera:
find . -name /*.xml | xargs grep -l "<beans" | xargs grep singleton
Luego me topé con archivos con espacios que, por supuesto, rompieron el comando anterior. Lo modifiqué de la siguiente manera para tratar con los espacios:
find . -name /*.xml -print0 | xargs -0 grep -l "<beans" | xargs grep singleton
La opción -print0 le dice a find que use print null como separador en lugar de espacio y -0 le dice a xargs que espera un valor nulo. Esto funciona siempre y cuando ninguno de los archivos que estoy buscando tenga espacios en sus rutas, pero se rompe si lo hacen.
Entonces, lo que necesito es una bandera para decirle a grep que imprima nulo como speartor en lugar de newline.
¿Algunas ideas?
Buena pregunta. Puedes hacer que grep -l use nulls como un delimitador con la opción Z:
find . -name /*.xml -print0 | xargs -0 grep -lZ "<beans" | xargs grep singleton
También puede hacer que xargs sea el carácter de nueva línea como delimitador. Eso debería funcionar también:
find . -name /*.xml -print0 | xargs -0 grep -l "<beans" | xargs "--delimiter=/n" grep singleton
La primera solución es mejor sin embargo.
find . -name "*.xml" -exec grep -q "<beans" {} /; -exec grep -q "singleton" {} /; -print
Si planea usar estos nombres de archivo en una secuencia de tubería posterior como lo ha hecho anteriormente, cambie -print
a -print0
Si usa GNU Parallel en lugar de xargs, puede evitar lidiar con esto, ya que GNU Parallel se divide de forma predeterminada en líneas nuevas en lugar de espacios en blanco.
find . -name /*.xml | parallel grep -l "<beans" | parallel grep singleton
Mira los videos introductorios para obtener más información: https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1
Para evitar el problema de espacio, usaría un nuevo carácter de línea como separador para xargs con la opción -d:
xargs -d ''/n'' ...
Para las dos búsquedas de patrones separadas, usaría egrep:
egrep ''(pattern one|pattern two)'' ...
Entonces mi solución completa sería:
find . -name /*.xml | xargs -d ''/n'' egrep ''(pattern one|pattern two)''