Comment fonctionne l'option «il y a 1 mois» dans la commande date?

22

Je ne sais pas si cela obtient la date passée dans la journée en cours ou si cela ne prend que 30 ou 31 jours.

par exemple

Si la date actuelle est March 28th, il y a 1 mois February 28th, mais que se passe-t-il quand c'est March 30th?

Scénario

Je veux sauvegarder certains fichiers chaque jour, le script enregistrera ces fichiers dans la date actuelle avec un $(date +%Y%m%d)format, comme 20150603_bckp.tar.gz, puis le mois suivant, supprimez tous ces fichiers dans le mois 1 sauf les fichiers du 1er et du 15e, c'est donc Mon état:

past_month = $(date -d "-1 month" +%Y%m%d)
day = $(date +%d)
if [ "$day" != 01 ] && [ "$day" != 15 ]
then
    rm /path/of/files/${past_month}_bckp.tar.gz
    echo "Depuration done"
else
    echo "Keep file"
fi

Mais je veux savoir, que se passera-t-il lorsque la date est le 30, le 31 ou même l'exemple de février dernier? Il conservera ces fichiers? ou supprimer les fichiers du premier jour?

Quand c'est le 31, la dépuration s'exécutera, donc si le mois dernier n'avait que 30 jours, cela supprimera le premier fichier du jour?

J'espère que j'ai laissé entendre.

tachomi
la source
1
Ne sauriez-vous pas que je suis ici le 30 mars pour cette raison exacte
user7203

Réponses:

24

- 1 monthen soustraira un du numéro du mois, puis si la date résultante n'est pas valide ( February 30par exemple), ajustez-la pour qu'elle soit valide. Il en December 31 - 1 monthest ainsi December 1, pas un jour en novembre, et March 31 - 1 monthestMarch 3 (sauf s'il est exécuté au cours d'une année bissextile).

Voici une citation de la page d'informations de Gnu date(qui est la dateversion qui implémente cette syntaxe), qui comprend une bonne suggestion pour rendre l'arithmétique plus robuste:

Le duvet en unités peut provoquer des problèmes avec les éléments relatifs. Par exemple, 2003-07-31 -1 monthpeut être évalué à 2003-07-01, car 2003-06-31 est une date non valide. Pour déterminer le mois précédent de manière plus fiable, vous pouvez demander le mois précédant le 15 du mois en cours. Par exemple:

    $ date -R
    Thu, 31 Jul 2003 13:02:39 -0700
    $ date --date='-1 month' +'Last month was %B?'
    Last month was July?
    $ date --date="$(date +%Y-%m-15) -1 month" +'Last month was %B!'
    Last month was June!

Un autre avertissement, également cité sur la page d'informations:

Faites également attention lorsque vous manipulez les dates en fonction des changements d'horloge, comme les sauts d'heure d'été. Dans certains cas, ceux-ci ont ajouté ou soustrait jusqu'à 24 heures à l'horloge, il est donc souvent judicieux d'adopter l'heure universelle en définissant la TZvariable d'environnement sur UTC0 avant de se lancer dans des calculs calendaires.

rici
la source
J'ai un doute ici, en particulier dans la situation de février ... Quand c'est le 29, 30 ou 31 mars, cela peut prendre le numéro suivant du mois dernier si celui-ci n'existe pas, donc dans ces trois situations, cela peut prendre 1er mars non? Car si les 29, 30, 31 mars puis les 1, 2 et 3 mars comme vous l'avez dit, alors le 1er avril sera le 4 mars en raison de la restructuration (je ne sais pas si c'est bien dit) qui a été faite, qu'en pensez-vous ?
tachomi
Un mois avant le 1er avril est le 1er mars et un mois avant le 1er mars est le 1er février. Ce ne sont pas des problèmes. Le problème est qu'un mois avant le 31 mai est le 1er mai parce que le 31 avril n'existe pas. Vous devez vérifier le numéro de jour de la date du mois précédent, et non le jour de la date actuelle.
rici
2
Ah! Le fait que "il y a un mois" de certains jours spécifiques dans n'importe quel mois puisse résulter dans le même mois n'est rien que j'attends d'une dateimplémentation; dans mon livre, c'est sémantiquement contre-intuitif. - Merci de l'avoir signalé, c'est bon à savoir.
Janis
2

Au lieu de vous fier aux noms de fichiers pour purger vos fichiers de sauvegarde, vous seriez plus sûr de vous fier à leurs métadonnées temporelles.

Par exemple, vous pouvez supprimer tous les fichiers de plus de 30 jours avec cette commande:

/usr/bin/find /path/to/your/files -type f -ctime +30 -delete

En bonus gratuit, le faire tous les jours vous permettra de conserver vos fichiers de sauvegarde sur un mois glissant, permettant une meilleure gestion de l'espace disque.

Pour conserver les 1er ou 15e fichiers, vous pouvez soit les stocker dans un autre répertoire, soit mettre à jour la commande find avec l'option -not -name.

Bertrand Lupart
la source
0

Vous pouvez essayer de voir comment fonctionne la date comme suit:

date -d "$(date -d "Mar 31 2019" +%F) +1 month ago"
Sun Mar  3 00:00:00 EET 2019

Je pense donc que sur la base du mois dernier courant (pas courant, si c'est mars), diminue le nombre de jours à partir du dernier mois du mois courant.

Vous pouvez essayer la syntaxe suivante pour supprimer des fichiers antérieurs à un certain nombre de jours (dans l'exemple ci-dessous 31 jours). Une ligne pour résoudre le problème (c'est pour une approche simple).

find /path/to/folder/with/arhives/ -mindepth 1 -mtime +31 -delete

Pour une approche plus détaillée, vous pouvez également faire quelque chose comme ceci: 1. Trouver le nombre de jours pour le mois courant:

cal $(date +%m) $(date +%y) | egrep -v "$(date +%y)|Su" | xargs | awk '{print $NF}'
  1. Trouver le nombre de jours du dernier mois:

    echo "$ (cal $ (date +% m) $ (date +% y) | egrep -v" $ (date +% y) | Su "| xargs | awk '{print $ NF}') -" $ ( cal $ (date -d "il y a +1 mois" +% m) $ (date +% y) | egrep -v "$ (date +% y) | Su" | xargs | awk '{print $ NF}') | avant JC

  2. Alors maintenant, nous trouvons la différence entre ces deux mois:

    echo "$ (cal $ (date +% m) $ (date +% y) | egrep -v" $ (date +% y) | Su "| xargs | awk '{print $ NF}') -" $ ( cal $ (date -d "il y a +1 mois" +% m) $ (date +% y) | egrep -v "$ (date +% y) | Su" | xargs | awk '{print $ NF}') | avant JC

Permet maintenant d'assigner quelques variables à ces 3 étapes. Étape 1 Nom de la variable: FCM Étape 2 Nom de la variable: FLM Étape 3 Variable NAme: DCL

FCM=$(cal $(date +%m) $(date +%y) | egrep -v "$(date +%y)|Su" | xargs | awk '{print $NF}')
FLM=$(al $(date -d "+1 month ago" +%m) $(date +%y) | egrep -v "$(date +%y)|Su" | xargs | awk '{print $NF}')
DCL=$(echo "$FCM-$FLM" | bc)

Vérifiez si $ DCL est égal à 0 (zéro) et supprimez en fonction de la différence entre $ FCM et $ FLM:

if [ $DCL -ne 0 ]; then
    if [ $DCL -lt 0 ]; then
        find /path/to/folder/with/arhives/ -mindepth 1 -mtime +$(echo "$DCL+$FLM" | bc) -delete
    elif [ $DCL -gt 0 ]; then
        find /path/to/folder/with/arhives/ -mindepth 1 -mtime +$(echo "$DCL+$FLM" | bc) -delete
    fi
else
    find /path/to/folder/with/arhives/ -mindepth 1 -mtime +$FLM -delete
fi

Vous pouvez également ajouter une variable à "/ path / to / folde / with / arhives /".

Conclusion: Si vous souhaitez supprimer des fichiers antérieurs à un mois (exactement), vous devez ajuster le nombre exact de jours, si vous utilisez la commande "date" et "il y a +1 mois".

Mihai M
la source