Rimuovere in modo ricorsivo i file


140

Qualcuno ha una soluzione per rimuovere quei fastidiosi file ._ e .DS_Store che si ottengono dopo aver spostato i file da un Mac a un server Linux?

specificare una directory iniziale e lasciarla andare? come / var / www / html / down ...


Anche se non è un duplicato IMO, si dovrebbe dare un'occhiata a questo: stackoverflow.com/questions/1280429/...
Grundlefleck

Anche se non è quello che stai chiedendo. Direi che questa è una soluzione migliore: unix.stackexchange.com/questions/9665/…
Viktor,

Risposte:


169

passare alla directory e utilizzare:

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

Non testato, provali prima senza gli xargs!

È possibile sostituire il punto dopo aver trovato, con la directory, anziché passare prima alla directory.

find /dir/here ...

2
So che la sua domanda non l'ha fatta, ma non ricordo mai: il tuo esempio gestisce i nomi di file con spazi?
Grundlefleck,

4
Sì, questo è lo scopo di print0 e da -0 a xargs. Normalmente non gestirà correttamente gli spazi, tuttavia con print0 stamperà il nome del file con un carattere null alla fine della riga, che xarg con -0 userà quindi per passare l'intero percorso a xargs senza la possibilità di avere lo spazio bianco essere usato un secondo o un terzo parametro per il comando rm che potrebbe essere davvero male!
X-Istence,

7
@X: i più recenti findutils supportano -deleteun'azione, che potrebbe abbreviare questo. @JT: questa ricerca ricorsivamente sotto .. Dipende da quanti file e sottodirectory ci sono ... non puoi semplicemente vietare il caricamento?
effimero

1
L'uso del -rflag (ricorsivo) non è consigliato in questo caso poiché non si desidera eliminare alcuna directory.
Daniel Zohar

2
@IlmariKaronen: buon punto. Non command rmsarebbe una soluzione migliore (cioè più diretta)? (Con "diretto" intendo che si occupa specificamente del problema attuale e nient'altro, e quindi è meno probabile che abbia effetti collaterali indesiderati e sarà anche più autoesplicativo per chiunque debba mantenere il codice più tardi.)
iconoclasta il

93
find /var/www/html \( -name '.DS_Store' -or -name '._*' \) -delete

86

I più recenti findutils supportano -delete, quindi:

find . -name ".DS_Store" -delete

Aggiungi -printper ottenere anche un elenco di eliminazioni.

Il comando funzionerà per te se hai un sistema POSIX aggiornato, credo. Almeno funziona per me su OS X 10.8 e funziona per altri che lo hanno testato su macOS 10.12 (Mojave).

Ringraziamo @ephemient in un commento sul post di @ X-Istence (pensato che fosse abbastanza utile da giustificare la propria risposta).


1
Funziona anche in OSX 10.6.
hoss,

3
Soluzione più pulita e semplice, +1!
limist

6
@OneOfOne: come dice il mio commento, ho ricevuto questo da @ effemerente. Come un principiante per colpire, ho trovato la tua soluzione (forse più corretta) molto meno leggibile e utilizzabile. Possono essere funzionalmente identici ma trovo che questa sintassi fornisca maggiore chiarezza.
rastrellare il

1
Il '.' non è necessario perché, findper impostazione predefinita, ricorre nella directory di lavoro corrente.
Tom Russell,

Nelle versioni più recenti del programma, la directory potrebbe essere omessa e implicherà la directory di lavoro corrente ( wikipedia ). Hai ancora bisogno .su macOS 10.12 (Sierra).
Dem Pilafian,

18

Comando semplice:

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

In bocca al lupo!


1
Funziona benissimo. MA una parola di cautela, ho appena usato questa rm -i ricerca ./ -name '* py'` -rf , which did NOT prompt me to delete files. you will need to take it on the end (i.e. -rfi`). Grazie a Dio per il mio script di backup.
ryanjdillon,

1
Se ci sono troppi file questo si rompe con l'errore:-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

2
Mi è piaciuto di più questo semplicemente perché "rm" non ha "-r" che non è necessario per questo compito specifico.
lotsoffreetime,

6

È possibile passare a zsh invece di bash. Ciò consente di utilizzare ** per abbinare i file in qualsiasi punto di un albero di directory:

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

Puoi anche combinarli in questo modo:

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

Zsh ha molte altre funzionalità a cui manca Bash, ma vale la pena fare una sola operazione. È disponibile nella maggior parte (probabilmente in tutte) le distribuzioni Linux, nonché in Cygwin e OS X.

Puoi trovare maggiori informazioni sul sito zsh .


1
Un possibile problema: poiché non usi xargs, potresti imbatterti nella restrizione della lunghezza degli argomenti della riga di comando. Inoltre, Bash 4 supporta **anche :-) (anche se non per impostazione predefinita, shopt -s globstardeve essere impostato)
effimero

4
find . -name "FILE-TO-FIND"-exec rm -rf {} \;

L'uso di exec per ogni file trovato non è veloce. È più veloce trovarli stamparli e quindi usare xargs per invocare rm una volta.
X-Istence,

3
Tuttavia, se hai un findsupporto che lo supporta, +è simile a xargs: find . -name "FILE-TO-FIND" -exec rm -rf {} +- (anche, ti manca uno spazio prima -exec)
Messo in pausa fino a nuovo avviso.

3
non abbiamo mai avuto xargs ai miei tempi. E abbiamo dovuto andare a scuola a piedi, in salita in entrambi i modi .......
Martin Beckett,

3

Esempio per eliminare "Thumbs.db" in modo ricorsivo;

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

Convalida da:

find . -iname "Thumbs.db"

Questo dovrebbe ora, non visualizzare nessuna delle voci con "Thumbs.db", all'interno del percorso corrente.


Assicurati che la tua risposta stampi un elenco di ciò che viene eliminato e spiega perché qualcuno potrebbe voler usare xargse print0invece di exec(ci sono ragioni).
Josh Habdas,


2

se hai Bash 4.0 ++

#!/bin/bash
shopt -s globstar
for file in /var/www/html/**/.DS_Store /var/www/html/**/._ 
do
 echo rm "$file"
done

2
L'esecuzione di una nuova copia di rm per ogni file è dispendiosa.
X-Istence,

2
@ X-Istence l'ottimizzazione prematura è dispendiosa
Lucina

Votato per originalità e utilizzo delle più recenti innovazioni bash.
Josh Habdas,

1

Alcune cose da notare:

'-delete' non è ricorsivo. Quindi, se .TemporaryItems (cartella) contiene file, il comando non riesce.

Ci sono molti di questi fastidiosi file creati dai mac: .DS_Store ._. DS_Store .TemporaryItems .apdisk

Questo comando è indirizzato a tutti loro. I salvataggi della corsa vengono ripetuti più volte per più partite.

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

0

Questo funziona anche:

sudo rm -rf 2018-03-*

qui i tuoi file eliminati con i nomi del formato 2018-03- (qualcos'altro)

mantienilo semplice


Non spieghi quando qualcuno potrebbe voler aggiungere un comando con prefisso sudoné fornire alcuna informazione su come rmfunziona nel contesto della tua risposta.
Josh Habdas,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.