Solution sans problèmes avec "ls" (fichiers nommés étranges)
Ceci est une combinaison de la réponse de ceving et d'anubhava. Les deux solutions ne fonctionnent pas pour moi. Parce que je cherchais un script qui devrait s'exécuter tous les jours pour sauvegarder des fichiers dans une archive, je voulais éviter les problèmes avec ls
(quelqu'un aurait pu enregistrer un fichier nommé drôle dans mon dossier de sauvegarde). J'ai donc modifié les solutions mentionnées pour répondre à mes besoins.
Ma solution supprime tous les fichiers, sauf les trois fichiers les plus récents.
find . -type f -printf '%[email protected]\t%p\n' |
sort -t $'\t' -g |
head -n -3 |
cut -d $'\t' -f 2- |
xargs rm
Quelques explications :
find
répertorie tous les fichiers (pas les répertoires) dans le dossier actuel. Ils sont imprimés avec des horodatages.
sort
trie les lignes en fonction de l'horodatage (la plus ancienne en haut).
head
imprime les lignes du haut, jusqu'aux 3 dernières lignes.
cut
supprime les horodatages.
xargs
exécute rm
pour chaque fichier sélectionné.
A vous de vérifier ma solution :
(
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
)
Cela crée 5 fichiers avec des horodatages différents dans le dossier actuel. Exécutez d'abord ce script, puis le code de suppression des anciens fichiers.
Cela listera tous les fichiers sauf les trois plus récents :
ls -t | tail -n +4
Cela supprimera ces fichiers :
ls -t | tail -n +4 | xargs rm --
Cela listera également les dotfiles :
ls -At | tail -n +4
et supprimer avec dotfiles :
ls -At | tail -n +4 | xargs rm --
Mais attention :analyse ls
peut être dangereux lorsque les noms de fichiers contiennent des caractères amusants comme des retours à la ligne ou des espaces. Si vous êtes certain que vos noms de fichiers ne contiennent pas de caractères amusants, analysez ls
est assez sûr, encore plus s'il s'agit d'un script à usage unique.
Si vous développez un script pour une utilisation répétée, vous ne devez certainement pas analyser la sortie de ls
et utilisez les méthodes décrites ici :http://mywiki.wooledge.org/ParsingLs
ls -t | tail -n +4 | xargs -I {} rm {}
Si vous voulez un 1 doublure
Ce qui suit semble un peu compliqué, mais il est très prudent d'être correct, même avec des noms de fichiers inhabituels ou intentionnellement malveillants. Malheureusement, il nécessite des outils 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 --
Explication du fonctionnement :
- Trouver émet
<mtime> <filename><NUL>
pour chaque fichier du répertoire courant. sort -g -z
effectue un tri numérique général (virgule flottante, par opposition à entier) basé sur la première colonne (fois) avec les lignes séparées par des NUL.- Le premier
read
dans lewhile
la boucle supprime le mtime (n'est plus nécessaire aprèssort
est terminé). - Le deuxième
read
dans lewhile
boucle lit le nom du fichier (jusqu'à la valeur NUL). - La boucle incrémente, puis vérifie, un compteur ; si l'état du compteur indique que nous avons dépassé le saut initial, alors nous imprimons le nom du fichier, délimité par un NUL.
xargs -0
puis ajoute ce nom de fichier dans la liste argv qu'il collecte pour invoquerrm
avec.