usuario sintaxis renombrar nombres nombre espacios espacio eliminar directorios directorio crear correcta con comando carpetas blanco archivos bash grep find xargs

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)''