Elimina tutti i file casuali tranne 1000 in una directory


13

Lascio che uno script di generazione dei dati funzioni troppo a lungo ora ho oltre 200.000 file di cui ho bisogno fino a circa 1000. Dalla riga di comando di Linux, c'è un modo semplice per eliminare tutti tranne 1000 di questi file, dove i file che verrebbero conservati non avrebbe alcuna dipendenza dal nome del file o da qualsiasi altro attributo?


Il processo che ha creato i file ha una caratteristica che collega ogni file a quello precedente? In tal caso, che selezionare a caso sarebbe importante ottenere un campione rappresentativo. Se il processo ha generato file casuali per natura, potresti semplicemente eliminare tutto dopo il primo 1000.
fixer1234

Risposte:


15

Elimina tutti i file casuali tranne 1000 in una directory

Codice:

find /path/to/dir -type f -print0 | sort -zR | tail -zn +1001 | xargs -0 rm

Spiegazione:

  1. Elenca tutti i file /path/to/dircon find;
    • print0: usa \0( carattere null ) come delimitatore di riga; quindi i percorsi dei file contenenti spazi / newline non interrompono lo script
  2. Mischia l'elenco dei file con sort;
    • -z: usa \0(carattere null) come delimitatore, anziché \n(una nuova riga)
    • -R: ordine casuale
  3. Rimuovere le prime 1000 righe dall'elenco randomizzato con tail;
    • -z: tratta l'elenco come delimitato da zero (come con sort)
    • -n +1001: mostra le righe a partire da 1001 (es. ometti le prime 1000 righe)
  4. xargs -0 rm - rimuovere i file rimanenti;
    • -0: delimitato da zero, di nuovo

Perché è meglio della soluzione di quixotic *:

  1. Funziona con nomi di file contenenti spazi / newline.
  2. Non tenta di creare alcuna directory (che potrebbe già esistere, tra l'altro).
  3. Non sposta alcun file, non tocca nemmeno i 1000 "file fortunati" oltre a elencarli con find.
  4. Evita di perdere un file nel caso in cui l'output di findnon finisca con \n(newline) per qualche motivo.

* - Ringrazio il chiassoso per | sort -R | head -1000, mi ha dato un punto di partenza.


In esecuzione su CentOS 6 stavo ricevendo errori su operandi non validi. Fortunatamente non mi occupo degli spazi nei percorsi dei file, quindi la rimozione di quegli operandi ha funzionato per mefind . -type f | sort -R | tail -n +1001 | xargs rm
Brad

@brad Potresti fornire i messaggi di errore e la tua versione di find? Proverò a migliorare la mia risposta, ho solo bisogno di alcuni input con cui lavorare.
rld.

3
tail: invalid option -- 'z'la versione della coda che ho è la 8.4
brad

Aggiungerei --no-run-if-empty a xargs per evitare errori se non ci sono file (dopo averlo eseguito due volte per esempio)
fraff

1

Utilizzare una directory temporanea, quindi findtutti i file, randomizzare l'elenco con sorte spostare i primi 1000 dell'elenco nella directory temporanea. Elimina il resto, quindi sposta i file indietro dalla directory temporanea.

$ mkdir ../tmp-dir
$ find . -type f | sort -R | head -1000 | xargs -I "I" mv I ../tmp-dir/
$ rm ./*
$ mv ../tmp-dir/* .

Se xargslamenta lunghezza della linea, utilizzare un numero minore di heade ripetere il comando come necessario (cioè, cambiamento -1000di -500ed eseguirlo due volte o modifica -200ed eseguirlo 5 volte).

Non riuscirà anche a gestire i nomi di file che includono spazi; come @ risposta di RLD spettacoli, si può usare find's -print0argomento, gli -zargomenti per sorte head, e -0con xargsal fine di garantire la gestione corretta nome del file.

Infine, se tmp-diresiste già, è necessario sostituire un nome di directory che non esiste.


Ciò fallirà se uno dei nomi di file elencati findinclude uno spazio.
rld.

0

Per gli utenti Mac dovrebbe fare il seguente script.

find . -type f -print0 | tr '\0' '\n' | sort -R | tail -n +10000 | tr '\n' '\0' | xargs -0 rm

trconsentirà all'ordinamento e alla coda di lavorare sugli elenchi \ninvece di \0.


-2

Il più semplice potrebbe essere rm -rf la directory, quindi rieseguire lo script di generazione dei dati assicurandosi di non eseguire troppo a lungo.


Non è quello che ha chiesto l'OP. Forse farlo non è fattibile.
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.