Risposte:
Se si desidera eseguire il loop dei file, non utilizzare mails
*. tl; dr Ci sono molte situazioni in cui finiresti per cancellare il file sbagliato, o anche tutti i file.
Detto questo, sfortunatamente questa è una cosa difficile da fare proprio in Bash. C'è una risposta funzionante a una domanda duplicata mia ancora più vecchiafind_date_sorted
che puoi usare con piccole modifiche:
counter=0
while IFS= read -r -d '' -u 9
do
let ++counter
if [[ counter -gt 3 ]]
then
path="${REPLY#* }" # Remove the modification time
echo -e "$path" # Test
# rm -v -- "$path" # Uncomment when you're sure it works
fi
done 9< <(find . -mindepth 1 -type f -printf '%TY-%Tm-%TdT%TH:%TM:%TS %p\0' | sort -rz) # Find and sort by date, newest first
* Senza offesa, ho usato anche ls
prima. Ma non è davvero sicuro.
Modifica: Nuovofind_date_sorted
con test unitari.
((++counter>3))
come test. È piacevolmente succinto. Per quanto riguarda gli oneliners: se la brevità è una preoccupazione avvolgere il codice in una funzione, non preoccuparti.
Per eliminare tutti tranne i 3 file più recenti utilizzando un zsh glob, è possibile utilizzare Om
(maiuscola O) per ordinare i file dal più vecchio al più recente e un pedice per acquisire i file desiderati.
rm ./*(Om[1,-4])
# | |||| ` stop at the 4th to the last file (leaving out the 3 newest)
# | |||` start with first file (oldest in this case)
# | ||` subscript to pick one or a range of files
# | |` look at modified time
# | ` sort in descending order
# ` start by looking at all files
Altri esempi:
# delete oldest file (both do the same thing)
rm ./*(Om[1])
rm ./*(om[-1])
# delete oldest two files
rm ./*(Om[1,2])
# delete everything but the oldest file
rm ./*(om[1,-2])
Il metodo di gran lunga più semplice è usare zsh e le sue qualificazioni glob : Om
ordinare in ordine decrescente di età (ovvero prima i più vecchi) e [1,3]
conservare solo le prime tre partite.
rm ./*(Om[1,3])
Vedi anche Come filtrare un glob in zsh per altri esempi.
E segui i consigli di l0b0 : il tuo codice si spezzerà in modo orribile se hai nomi di file che contengono caratteri speciali della shell.
È possibile utilizzare la seguente funzione per ottenere il file più recente in una directory:
newest_in()
{
local newest=$1
for f;do [[ $f -nt $newest ]] && newest="$f"; done;
printf '%s\n' "$newest"
}
Dagli un set diverso di file sostituendo il file più recente dopo ogni iterazione.
Suggerimento: se si tiene il set iniziale di file in un array chiamato "$ {files [@]}", quindi salvare l'indice del file più recente trovato e unset 'files[index]'
prima della successiva iterazione.
Uso: newest_in [set of files/directories]
Uscita campione:
[rany$] newest_in ./*
foo.txt
[rany$]
Innanzitutto, l' -R
opzione è per la ricorsione, che probabilmente non è quello che vuoi - che cercherà anche in tutte le sottodirectory. In secondo luogo, l' <
operatore (quando non viene visto come reindirizzamento) è per il confronto delle stringhe. Probabilmente vuoi -lt
. Provare:
while [ `ls -1A | grep ^- | wc -l` -lt 3 ]
Ma userei trovare qui:
while [ `find . -maxdepth 1 -type f -print | wc -l` -lt 3 ]
So che è un peccato analizzare ls
, ma che dire di questo:
find . -type f -maxdepth 1 | xargs ls -ltr | sed '1,3d' | awk '{print $9}' | xargs rm
Un test rapido con 5 file vuoti:
$ >1
$ >2
$ >3
$ >4
$ >5
$ find . -type f -maxdepth 1 | xargs ls -lt | sed '1,3d' | awk '{print $9}' | xargs rm
$ ls -1
3
4
5
ls
dell'output e utilizzo find
e xargs
insieme nel modo sbagliato. Se si combinano find
e xargs
vi consiglio di utilizzare find
s -print0
e di conseguenza xargs
s -O
opzioni. Leggi Utilizzando Ricerca per ulteriori informazioni su questo argomento. Potresti anche dare un'occhiata e leggere perché analizzare Psing è molto male.
Questo one-liner fa tutto ciò che penso:
ls -t1 /home/user/test | tail -n +4 | xargs -I{} rm -- "{}"
Ecco una soluzione:
rm /appserver/webapplogs/$(ls -t1 /appserver/webapplogs/|tail -1)