La canalización de find -name a xargs produce nombres de archivo con espacios que no se pasan al comando

26

Normalmente para eliminar archivos con espacios en su nombre de archivo, debería ejecutar:

$ rm "file name"

pero si quiero eliminar varios archivos, por ejemplo:

$ find . -name "*.txt" | xargs rm

Esto no eliminará archivos con espacios en ellos.

Ashley
fuente
Adivina aquí: ¿ find -name "*\ *.txt" | xargs rmfunciona para archivos de dos palabras?
TheWanderer

Respuestas:

49

Puedes decir findy xargsusar ambos terminadores nulos

find . -name "*.txt" -print0 | xargs -0 rm

o (más simple) use la -deleteacción integrada defind

find . -name "*.txt" -delete

o (gracias @kos)

find . -name "*.txt" -exec rm {} +

cualquiera de los cuales debe respetar el ARG_MAXlímite del sistema sin la necesidad de xargs.

conductor de acero
fuente
1
No puedo votarlo dos veces difícil :) ya que mencionaste ARG_MAXque también mencionaré que find . -name "*.txt" -exec rm {} \;sería un "tiro seguro"
kos
3
Así dice el maestro: recuerda siempre xargs -0.
Joshua
1
Punto súper importante: -print0debe ser la última opción (o al menos después -name "*.txt"), de lo contrario, esto afectará a los archivos que ya no se limitan a*.txt ...
Kev
1

Por cierto, si usó algo más que buscar, puede usar tr para reemplazar las nuevas líneas con bytes nulos.

P.ej. La siguiente línea elimina los 10 últimos archivos modificados en un directorio, incluso si tienen espacios en sus nombres.

ls -tp | grep -v / | head -n 10 | tr "\n" "\0" | xargs -0 rm

Ibrahim
fuente
Sí, esto funciona.
Peter Mortensen
0

El comando xargs usa tabuladores, espacios y nuevas líneas como delimitadores por defecto. Puede decirle que solo use caracteres de nueva línea ('\ n') con la opción -d:

find . -name "*.txt" | xargs -d '\n' rm

Fuente de respuesta en SO .

joseph_morris
fuente
Esa respuesta menciona en -0lugar de -d(para xargs) los sistemas BSD. ¿Qué usa Ubuntu? La respuesta aceptada aquí utiliza -0. ¿Que es correcto?
Peter Mortensen