Script shell pour supprimer les répertoires de plus de n jours

165

J'ai des répertoires nommés comme suit:

2012-12-12
2012-10-12
2012-08-08

Comment supprimer les répertoires de plus de 10 jours avec un script shell bash?

bobsr
la source
1
A-t-il un rapport sur son temps réel de création / modification? Parce que findje pourrais le faire sans regarder le nom alors ...
Wrikken
ils devraient également avoir un temps de création / modification sur eux
bobsr
4
Qu'entendez-vous par «plus vieux que»? Faites-vous référence à l'heure à laquelle le répertoire a été créé, à l'heure à laquelle son contenu a été modifié pour la dernière fois ou à autre chose? Soyez prudent avec certaines des réponses ci-dessous; ctimeest le temps de changement d'inode. Pour un répertoire, il change lorsque des fichiers sont ajoutés ou supprimés du répertoire.
ajk

Réponses:

391

Cela le fera de manière récursive pour vous:

find /path/to/base/dir/* -type d -ctime +10 -exec rm -rf {} \;

Explication:

  • find: la commande unix pour rechercher des fichiers / répertoires / liens etc.
  • /path/to/base/dir: le répertoire dans lequel commencer votre recherche.
  • -type d: ne trouve que les répertoires
  • -ctime +10: ne considérez que ceux dont le temps de modification est supérieur à 10 jours
  • -exec ... \;: pour chaque résultat trouvé, exécutez la commande suivante dans ...
  • rm -rf {}: force récursivement la suppression du répertoire; la {}pièce est l'endroit où le résultat de la recherche est remplacé par la pièce précédente.

Sinon, utilisez:

find /path/to/base/dir/* -type d -ctime +10 | xargs rm -rf

Ce qui est un peu plus efficace, car cela revient à:

rm -rf dir1 dir2 dir3 ...

par opposition à:

rm -rf dir1; rm -rf dir2; rm -rf dir3; ...

comme dans la -execméthode.


Avec les versions modernes de find, vous pouvez remplacer le ;par +et il fera l'équivalent de l' xargsappel à votre place, en passant autant de fichiers que nécessaire à chaque appel système exec:

find . -type d -ctime +10 -exec rm -rf {} +
sampson-chen
la source
13
-mtimeétait mieux pour moi car il vérifie les changements de contenu plutôt que les changements d'autorisation, sinon c'était parfait.
quickshift du
7
Je pense que cela supprimera également le répertoire de base lui
Ou Gal
3
@OrGal vous avez tout à fait raison. Pour éviter cela, il suffit d' utiliser: find /path/to/base/dir/*.
zloynemec
11
vous pouvez utiliser -maxdepth 1 pour ignorer le contenu des répertoires
Sam
7
L'approche la plus efficace peut se retourner contre vous si vous avez trop de dossiers à supprimer: stackoverflow.com/questions/11289551/… . Pour la même raison, afin d'éviter la suppression du dossier de base, il est préférable d'utiliser -mindepth 1(plutôt que /path/to/folder/*).
Ohad Schneider
41

Si vous souhaitez supprimer tous les sous-répertoires sous /path/to/base, par exemple

/path/to/base/dir1
/path/to/base/dir2
/path/to/base/dir3

mais vous ne voulez pas supprimer la racine /path/to/base, vous devez ajouter -mindepth 1et d' -maxdepth 1options, qui ont accès uniquement les sous - répertoires/path/to/base

-mindepth 1exclut la racine /path/to/basedes correspondances.

-maxdepth 1sera seulement correspondre immédiatement sous les sous - répertoires /path/to/basetels que /path/to/base/dir1, /path/to/base/dir2et , /path/to/base/dir3mais il ne sera pas la liste des sous - répertoires de ces d'une manière récursive. Ainsi, ces exemples de sous-répertoires ne seront pas répertoriés:

/path/to/base/dir1/dir1
/path/to/base/dir2/dir1
/path/to/base/dir3/dir1

et ainsi de suite.

Donc, pour supprimer tous les sous-répertoires sous /path/to/baselesquels datent de plus de 10 jours;

find /path/to/base -mindepth 1 -maxdepth 1 -type d -ctime +10 | xargs rm -rf
pmgarvey
la source
20

findprend en charge l' -deleteopération, donc:

find /base/dir/* -ctime +10 -delete;

Je pense qu'il y a un hic que les fichiers doivent également être âgés de plus de 10 jours. Je n'ai pas essayé, quelqu'un peut confirmer dans les commentaires.

La solution la plus votée ici est manquante -maxdepth 0, elle appellera donc rm -rfchaque sous-répertoire, après sa suppression. Cela n'a pas de sens, alors je suggère:

find /base/dir/* -maxdepth 0  -type d -ctime +10 -exec rm -rf {} \;

La -deletesolution ci-dessus n'utilise pas -maxdepth 0car findse plaindre que le répertoire n'est pas vide. Au lieu de cela, cela implique -depthet supprime de bas en haut.

Ondra Žižka
la source
Je peux confirmer les -deletetravaux, mais comme vous l'avez dit, vous ne pouvez l'utiliser que pour supprimer des répertoires vides, un peu comme rmdir.
CTodea
3

J'avais du mal à y parvenir en utilisant les scripts fournis ci-dessus et d'autres scripts, en particulier lorsque les noms de fichiers et de dossiers avaient une nouvelle ligne ou des espaces.

Finalement, je suis tombé sur tmpreaper et cela a plutôt bien fonctionné pour nous jusqu'à présent.

tmpreaper -t 5d ~/Downloads


tmpreaper  --protect '*.c' -t 5h ~/my_prg

Lien source d'origine

Possède des fonctionnalités telles que test, qui vérifie les répertoires de manière récursive et les répertorie. Possibilité de supprimer des liens symboliques, des fichiers ou des répertoires et également le mode de protection d'un certain modèle lors de la suppression

user_v
la source
2

OU

rm -rf `find /path/to/base/dir/* -type d -mtime +10`

Version mise à jour et plus rapide de celui-ci:

find /path/to/base/dir/* -mtime +10 -print0 | xargs -0 rm -f
Impressionnant
la source
2
Celui-ci pourrait facilement dépasser la longueur maximale de la ligne de commande. Voir xargs --show-limits.
Michael Krupp
2
Ne fonctionnera pas non plus s'il y a des noms de fichiers contenant des espaces ou d'autres caractères spéciaux du shell.
Martin Tournoij
@Carpetsmoker Le -print0/ -0ne s'occupe- t-il pas des caractères spéciaux du shell, ou non?
mpen
Vous avez raison de dire que la xargsversion sera @mpen, mais pas la première ligne.
Martin Tournoij