Eliminar archivos de forma recursiva

140

¿Alguien tiene una solución para eliminar esos molestos archivos ._ y .DS_Store que se obtienen después de mover archivos de una Mac a un servidor Linux?

especificar un directorio de inicio y dejarlo ir? como / var / www / html / down ...

JT
fuente
Aunque no es un IMO duplicado, debería echar un vistazo a esto: stackoverflow.com/questions/1280429/…
Grundlefleck el
Aunque no es lo que estás preguntando. Yo diría que esta es una mejor solución: unix.stackexchange.com/questions/9665/…
Viktor

Respuestas:

169

cambie al directorio y use:

find . -name ".DS_Store" -print0 | xargs -0 rm -rf
find . -name "._*" -print0 | xargs -0 rm -rf

No probado, pruébalos sin los xargs primero.

Puede reemplazar el período después de buscar, con el directorio, en lugar de cambiar primero al directorio.

find /dir/here ...
X-Istence
fuente
2
Sé que su pregunta no lo hizo, pero nunca puedo recordar: ¿su ejemplo maneja nombres de archivos con espacios?
Grundlefleck
44
Sí, para eso está el print0 y el -0 para xargs. Normalmente no manejaría los espacios correctamente, sin embargo, con print0 imprimirá el nombre del archivo con un carácter nulo al final de la línea, que xarg con -0 usará para pasar la ruta completa a xargs sin la posibilidad de tener el espacio en blanco se usa un segundo o tercer parámetro para el comando rm que podría ser realmente malo.
X-Istence
77
@X: los nuevos findutils admiten una -deleteacción que podría acortar esto. @JT: Esto busca recursivamente debajo .. Depende de cuántos archivos y subdirectorios haya ... ¿no puede simplemente prohibir que se carguen?
Ephemient
1
Usando la -rbandera (recursivo) no se recomienda en este caso, ya que no quiere eliminar los directorios ..
Daniel Zohar
2
@IlmariKaronen: buen punto. ¿No command rmsería una solución mejor (es decir, más directa)? (Por "directo" me refiero a que trata específicamente con el problema en cuestión y nada más, y por lo tanto es menos probable que tenga efectos secundarios no deseados, y también será más claro para cualquiera que tenga que mantener el código más tarde.)
iconoclasta
93
find /var/www/html \( -name '.DS_Store' -or -name '._*' \) -delete
Uno de uno
fuente
86

Los nuevos soportes de findutils -delete, por lo tanto:

find . -name ".DS_Store" -delete

Agregar -printpara obtener también una lista de eliminaciones.

El comando funcionará para usted si tiene un sistema POSIX actualizado, creo. Al menos funciona para mí en OS X 10.8 y para otros que lo han probado en macOS 10.12 (Mojave).

Gracias a @ephemient en un comentario en la publicación de @ X-Istence (pensé que era lo suficientemente útil como para garantizar su propia respuesta).

rattray
fuente
1
También funciona en OSX 10.6.
hoss
3
¡La solución más limpia y simple, +1!
limist
66
@OneOfOne: como dice mi comentario, recibí esto de @ ephemient. Como principiante en bash, encontré su solución (quizás más correcta) mucho menos legible y utilizable. Pueden ser funcionalmente idénticos, pero creo que esta sintaxis proporciona más claridad.
Rattray
1
Los '.' no es necesario porque se findrepite en el directorio de trabajo actual de forma predeterminada.
Tom Russell
En versiones más recientes del programa, el directorio puede omitirse e implicará el directorio de trabajo actual ( wikipedia ). Aún lo necesitas .en macOS 10.12 (Sierra).
Dem Pilafian
18

Comando simple:

rm `find ./ -name '.DS_Store'` -rf
rm `find ./ -name '._'` -rf

¡Buena suerte!

KimKha
fuente
1
Esto funciona muy bien. PERO una palabra de precaución, acabo de usar este rm -i hallazgo ./ -name '* py'` -rf , which did NOT prompt me to delete files. you will need to take it on the end (i.e. -rfi`). Gracias a Dios por mi script de respaldo.
ryanjdillon
1
Si hay demasiados archivos, esto rompe con el error:-bash: /bin/rm: Argument list too long
Viktor
12
cd /var/www/html && find . -name '.DS_Store' -print0 | xargs -0 rm
cd /var/www/html && find . -name '._*' -print0 | xargs -0 rm
mopoke
fuente
2
Este me gustó más simplemente porque "rm" no tiene "-r", lo cual no es necesario para esta tarea específica.
lotsoffreetime
6

Puede cambiar a zsh en lugar de bash. Esto le permite usar ** para hacer coincidir archivos en cualquier parte de un árbol de directorios:

$ rm /var/www/html/**/_* /var/www/html/**/.DS_Store

También puedes combinarlos así:

$ rm /var/www/html/**/(_*|.DS_Store)

Zsh tiene muchas otras características que bash carece, pero solo vale la pena hacer el cambio. Está disponible en la mayoría de las distribuciones de Linux (probablemente todas), así como en Cygwin y OS X.

Puede encontrar más información en el sitio zsh .

Dave Kirby
fuente
1
Un posible problema: dado que no usa xargs, puede encontrarse con la restricción de longitud del argumento de la línea de comandos. Además, Bash 4 **también es compatible :-) (aunque no de forma predeterminada, shopt -s globstardebe configurarse)
Ephemient
4
find . -name "FILE-TO-FIND"-exec rm -rf {} \;
Martin Beckett
fuente
Usar exec para cada archivo encontrado no es rápido. Es más rápido tener que imprimirlos y luego usar xargs para invocar rm una vez.
X-Istence
3
Sin embargo, si tiene una findque lo admite, +es similar a xargs: find . -name "FILE-TO-FIND" -exec rm -rf {} +- (también, le falta un espacio antes -exec)
Pausado hasta nuevo aviso.
3
Nunca tuvimos xargs en mi día. Y tuvimos que caminar a la escuela, cuesta arriba en ambos sentidos .......
Martin Beckett
3

Ejemplo para eliminar "Thumbs.db" recursivamente;

find . -iname "Thumbs.db" -print0 | xargs -0 rm -rf

Validar por:

find . -iname "Thumbs.db"

Esto debería ahora, no mostrar ninguna de las entradas con "Thumbs.db", dentro de la ruta actual.

parasitar
fuente
Asegúrese de que su respuesta imprima una lista de lo que se está eliminando y explique por qué alguien podría querer usar xargsy en print0lugar de exec(hay razones).
Josh Habdas
3

Es mejor ver qué se está eliminando agregando -print a esta respuesta

find /var/www/html \( -name '.DS_Store' -or -name '._*' \) -delete -print
Ahmad Yoosofan
fuente
2

si tienes Bash 4.0 ++

#!/bin/bash
shopt -s globstar
for file in /var/www/html/**/.DS_Store /var/www/html/**/._ 
do
 echo rm "$file"
done
ghostdog74
fuente
2
Ejecutar una nueva copia de rm para cada archivo es un desperdicio.
X-Istence el
2
@ X-Istence la optimización prematura es un desperdicio
Lucina
Votaron por la originalidad y el uso de innovaciones más recientes de bash.
Josh Habdas
1

Algunas cosas a tener en cuenta:

'-delete' no es recursivo. Entonces, si .TemporaryItems (carpeta) tiene archivos, el comando falla.

Hay muchos de estos molestos archivos creados por Mac: .DS_Store ._. DS_Store .TemporaryItems .apdisk

Este comando se dirige a todos ellos. Ahorra al ejecutar find una y otra vez para múltiples partidos.

find /home/foo \( -name '.DS_Store' -or -name '._.DS_Store' -or -name '._*' -or -name '.TemporaryItems' -or -name '.apdisk' \) -exec rm -rf {} \;
Karan Bhalla
fuente
0

Esto también funciona:

sudo rm -rf 2018-03-*

aquí estás eliminando archivos con nombres del formato 2018-03- (algo más)

mantenlo simple

pranavhd
fuente
No explica cuándo alguien puede querer prefijar un comando sudoni proporciona información sobre cómo rmfunciona en el contexto de su respuesta.
Josh Habdas