ls | grep | rm - ¿Cómo formatear este comando?

11

Estoy tratando de eliminar un montón de archivos en un determinado directorio (en Mac OS X usando Terminal)

ls | grep \([1-9]\) | xargs rm

debería hacer el truco, pero no es así. Estoy tratando de eliminar cualquier archivo con un solo dígito entre paréntesis en el nombre del archivo (duplicados descargados de la web), pero termina haciendo algo como esto:

> rm: 520syllabus2010: No such file or
> directory rm: (3).pdf: No such file or
> directory

porque no interpreta el espacio correcto. Debería eliminar "520syllabus2010 (3) .pdf"

¿Cuál es la forma correcta de hacer esto?

Gracias Jeff

Jeff
fuente
1
Su nombre de archivo de ejemplo no contiene un literal #.
Benjamin Bannier
1
@honk: Él no está buscando un literal #.
Ignacio Vazquez-Abrams
1
Debido a la expansión del shell, esto no funcionará como se esperaba si el cwd tiene un archivo llamado eg (3). Es mejor citar argumentos para que el shell no los afecte.
Ignacio Vazquez-Abrams
1
Estás siendo golpeado por el problema del separador en.wikipedia.org/wiki/Xargs#The_separator_problem
Ole Tange

Respuestas:

19

Version corta:

rm *\([1-9]\)*

No canalizar lsa xargs. En su lugar, diríjase find ... -print0a xargs -0, para evitar tales problemas.

find . -maxdepth 1 -name '*([1-9])*' -print0 | xargs -0 rm

... que se puede escribir como:

find . -maxdepth 1 -name '*([1-9])*' -exec rm {} \;

y:

find . -maxdepth 1 -name '*([1-9])*' -delete

que se puede acortar a solo rmcon un comodín.


Normalmente, lsy findlos nombres de archivos separados con saltos de línea, pero xargsdivide su entrada por salto de línea o espacio, lo que resulta en el comportamiento que se ve.

Es posible indicar xargsque se divida solo por nueva línea, pero los archivos también pueden tener nuevas líneas en sus nombres. De hecho, en Linux y BSD, el único carácter no permitido es el byte "nulo" o cero , por lo que es lo que debe usar en tales casos.

En el ejemplo 2 anterior, -print0le dice findque separe los nombres de archivo con un byte nulo; mismo para xargs -0. (Algunas otras herramientas también tienen opciones similares, como sort -zo grep -zZ).

La "versión corta" utiliza un comodín de shell simple ("patrón" en el bashmanual ; consulte la sección "Expansión del nombre de ruta").

usuario1686
fuente
1
Y solo para estar seguro, es mejor usarlo *" "\\([1-9]\\).*para que solo se eliminen los archivos con un espacio antes del número pareado antes del período (a, para ser justos).
Ignacio Vazquez-Abrams
No estoy muy familiarizado con esta sintaxis, pero en base a los votos positivos, lo probé y ¿qué sabes? ¡Funcionó! ¡Gracias!
Jeff
1
+1. -print0 es esencial para la correcta tubería a xargs.
Chris W. Rea