web-dev-qa-db-fra.com

bash: Supprime tous les fichiers de plus d'un mois, mais laisse les fichiers du lundi

J'ai beaucoup d'archives de sauvegarde quotidiennes. Pour gérer l'utilisation du disque, j'ai besoin d'un script bash qui supprime tous les fichiers de plus d'un mois, mais conserve tous les fichiers créés le lundi, même s'ils datent de plus d'un mois.

Par exemple, cela supprimera tous les fichiers modifiés pour la dernière fois il y a plus de 30 jours:

 find /path/to/files* -type f -mtime +30 -delete

Mais je ne sais pas vraiment comment conserver les fichiers créés le lundi.

10
freento

Version légèrement plus simple et plus prudente de la réponse de @ JoSo:

find /path/to/files -type f -mtime +30 \
    -exec sh -c 'test $(date +%a -r "$1") = Mon || echo rm "$1"' -- {} \;

Les différences:

  • Utiliser date -r pour obtenir directement la dernière date de modification d'un fichier
  • Utiliser %a pour travailler avec des noms de jour de semaine plus compréhensibles
  • Rappelez-vous simplement le rm "$1" premier à donner votre avis sur ce qui sera supprimé. Si cela vous convient, vous pouvez soit coller | sh à la fin pour exécuter réellement, soit supprimer la echo

Cependant, @JoSo a raison de souligner que date +%a dépend des paramètres régionaux. Ces versions seraient donc plus sûres:

find /path/to/files -type f -mtime +30 \
    -exec sh -c 'test $(date +%u -r "$1") = 1 || echo rm "$1"' -- {} \;
find /path/to/files -type f -mtime +30 \
    -exec sh -c 'test $(LC_TIME=C date +%a -r "$1") = Mon || echo rm "$1"' -- {} \;
13
janos

Comme find à ma connaissance n'a pas de vérification du jour de la semaine, vous devez appeler un programme externe.

find /path/to/files -type f -mtime +30 \
    -exec sh -c \
        '[ "$(date +%u -d @"$(stat -c %Y "$1")")" != 1 ] && rm "$1"' -- {} \;

Mise à jour: L'utilisation du commutateur -r en date (félicitations à Janos) et uniquement en testant et en ne supprimant pas dans la commande Shell donne probablement la version la plus propre possible:

find /path/to/files -type f -mtime +30 \
    -exec sh -c 'test "$(date +%u -r "$1")" != 1' -- {} \; \
    -print  # or -delete instead
6
Jo So

vous pouvez utiliser

stat -c %y yourfile

pour obtenir la date à laquelle le fichier a été créé.

Puis extrayez la date avec cut pour avoir un var comme myvar = yyyymmdd

et enfin utiliser

date +%u --d $myvar
date +%u --d 20130822

il reviendra le jour de la semaine, s'il retourne 1 c'était lundi. Dans mon cas, il retourne 4 parce que 22/08/2013 était un jeudi

Edit: si vous pouvez faire en sorte que tout cela fonctionne comme une simple ligne de commande, comme le suggère Jo So, c’est mieux!

0
user2196728

Qu'en est-il d'éviter les sous-processus en boucle:

find /path/to/files -type f -mtime +30 -printf '%Ta %p\n' \
    | grep -v ^Mon | cut -c5- | tr "\n" "\0" | xargs -0 rm -v
0
brablc