Soluzione senza problemi con "ls" (file con nomi strani)
Questa è una combinazione della risposta di ceving e di anubhava. Entrambe le soluzioni non funzionano per me. Poiché stavo cercando uno script che dovrebbe essere eseguito ogni giorno per il backup dei file in un archivio, volevo evitare problemi con ls
(qualcuno potrebbe aver salvato qualche file dal nome divertente nella mia cartella di backup). Quindi ho modificato le soluzioni menzionate per adattarle alle mie esigenze.
La mia soluzione elimina tutti i file, eccetto i tre file più recenti.
find . -type f -printf '%[email protected]\t%p\n' |
sort -t $'\t' -g |
head -n -3 |
cut -d $'\t' -f 2- |
xargs rm
Qualche spiegazione:
find
elenca tutti i file (non le directory) nella cartella corrente. Sono stampati con timestamp.
sort
ordina le righe in base al timestamp (il più vecchio in alto).
head
stampa le prime righe, fino alle ultime 3 righe.
cut
rimuove i timestamp.
xargs
esegue rm
per ogni file selezionato.
Per verificare la mia soluzione:
(
touch -d "6 days ago" test_6_days_old
touch -d "7 days ago" test_7_days_old
touch -d "8 days ago" test_8_days_old
touch -d "9 days ago" test_9_days_old
touch -d "10 days ago" test_10_days_old
)
Questo crea 5 file con diversi timestamp nella cartella corrente. Esegui prima questo script e poi il codice per eliminare i vecchi file.
Questo elencherà tutti i file tranne i tre più recenti:
ls -t | tail -n +4
Questo eliminerà quei file:
ls -t | tail -n +4 | xargs rm --
Questo elencherà anche i dotfile:
ls -At | tail -n +4
ed elimina con dotfiles:
ls -At | tail -n +4 | xargs rm --
Ma attenzione:parsing ls
può essere pericoloso quando i nomi dei file contengono caratteri divertenti come newline o spazi. Se sei sicuro che i tuoi nomi di file non contengano caratteri divertenti allora analizza ls
è abbastanza sicuro, ancora di più se si tratta di uno script unico.
Se stai sviluppando uno script per un uso ripetuto, non dovresti certamente analizzare l'output di ls
e utilizzare i metodi descritti qui:http://mywiki.wooledge.org/ParsingLs
ls -t | tail -n +4 | xargs -I {} rm {}
Se vuoi una fodera 1
Quanto segue sembra un po' complicato, ma è molto cauto per essere corretto, anche con nomi di file insoliti o intenzionalmente dannosi. Sfortunatamente, richiede strumenti GNU:
count=0
while IFS= read -r -d ' ' && IFS= read -r -d '' filename; do
(( ++count > 3 )) && printf '%s\0' "$filename"
done < <(find . -maxdepth 1 -type f -printf '%[email protected] %P\0' | sort -g -z) \
| xargs -0 rm -f --
Spiegando come funziona:
- Trova emette
<mtime> <filename><NUL>
per ogni file nella directory corrente. sort -g -z
esegue un ordinamento numerico generale (virgola mobile, anziché intero) basato sulla prima colonna (ora) con le righe separate da NUL.- Il primo
read
nelwhile
loop rimuove l'mtime (non più necessario doposort
è fatto). - Il secondo
read
nelwhile
ciclo legge il nome del file (in esecuzione fino al valore NUL). - Il ciclo incrementa, e quindi controlla, un contatore; se lo stato del contatore indica che abbiamo superato il salto iniziale, allora stampiamo il nome del file, delimitato da NUL.
xargs -0
quindi aggiunge quel nome file nell'elenco argv che sta raccogliendo per invocarerm
con.