Wie funktioniert die Option "Vor 1 Monat" im Datumsbefehl?


22

Ich bin mir nicht sicher, ob dies das letzte Datum innerhalb des aktuellen Tages ist oder ob es nur 30 oder 31 Tage dauert.

z.B

Wenn das aktuelle Datum ist March 28th, muss es 1 Monat her sein February 28th, aber was passiert, wenn es ist March 30th?

Szenario

Ich möchte jeden Tag einige Dateien sichern. Das Skript speichert diese Dateien innerhalb des aktuellen Datums mit dem $(date +%Y%m%d)Format. 20150603_bckp.tar.gzWenn dann der nächste Monat eintrifft, entfernen Sie alle diese Dateien innerhalb eines Monats mit Ausnahme der Dateien des ersten und des 15. Monats mein Zustand:

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

Aber ich möchte wissen, was passiert, wenn der Termin der 30., 31. oder sogar der vergangene Februar ist. Es wird diese Dateien behalten? oder am ersten Tag Dateien entfernen?

Wenn es der 31. ist, wird die Depuration ausgeführt. Wenn also der letzte Monat nur 30 Tage hatte, wird dadurch die erste Datei des Tages entfernt.

Ich hoffe ich habe angedeutet.


1
Würden Sie nicht wissen , ich bin hier am 30. März für diesen genauen Grund
user7203

Antworten:


24

- 1 monthsubtrahiert eins von der Monatszahl, und wenn das resultierende Datum nicht gültig ist ( February 30z. B.), stellen Sie es so ein, dass es gültig ist. Also December 31 - 1 monthist December 1kein Tag im November und March 31 - 1 monthist March 3(sofern nicht in einem Schaltjahr ausgeführt).

Hier ist ein Zitat von der Infoseite für Gnu date(die dateVersion, die diese Syntax implementiert), das einen guten Vorschlag enthält, um die Arithmetik robuster zu machen:

Die Unschärfe in Einheiten kann zu Problemen mit relativen Gegenständen führen. Beispiel: 2003-07-31 -1 monthWird möglicherweise auf 2003-07-01 ausgewertet, da 2003-06-31 ein ungültiges Datum ist. Um den Vormonat zuverlässiger zu bestimmen, können Sie den Monat vor dem 15. des aktuellen Monats anfordern. Beispielsweise:

    $ 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!

Eine weitere Warnung, auch aus der Infoseite zitiert:

Seien Sie auch vorsichtig, wenn Sie Datumsangaben rund um die Uhr ändern, z. B. um die Sommerzeit. In einigen Fällen wurden bis zu 24 Stunden von der Uhr addiert oder subtrahiert. Daher ist es oft ratsam, die Weltzeit zu übernehmen, indem Sie die TZUmgebungsvariable auf setzen, UTC0 bevor Sie mit den kalendarischen Berechnungen beginnen.


Ich habe hier einen Zweifel, speziell in der Februar-Situation ... Wenn es 29., 30. oder 31. März ist, könnte es die folgende Zahl des letzten Monats dauern, wenn die aktuelle nicht existiert, also könnte es in diesen drei Situationen dauern 1. März nein? Denn wenn der 29., 30., 31. März und dann der 1., 2., 3. März, wie Sie sagten, der 1. April der 4. März sein wird, weil die Umstrukturierung (ich weiß nicht, ob es gut gesagt ist) durchgeführt wurde, was denken Sie? ?
Tachomi

Ein Monat vor dem 1. April ist der 1. März und ein Monat vor dem 1. März ist der 1. Februar. Dies sind keine Probleme. Das Problem ist, dass ein Monat vor dem 31. Mai der 1. Mai ist, weil der 31. April nicht existiert. Sie sollten die Tagesnummer des Datums vor einem Monat und nicht den Tag des aktuellen Datums überprüfen.
rici

2
Doh! Die Tatsache, dass "vor einem Monat" an bestimmten Tagen in einem Monat zu demselben Monat führen kann, ist nichts, was ich von einer dateImplementierung erwarten würde . in meinem Buch ist es semantisch kontraintuitiv. - Danke für den Hinweis, es ist gut zu wissen.
Janis

2

Anstatt sich beim Löschen Ihrer Sicherungsdateien auf Dateinamen zu verlassen, sollten Sie sich sicherer auf deren Zeitmetadaten verlassen.

Beispielsweise können Sie mit diesem Befehl alle Dateien löschen, die älter als 30 Tage sind:

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

Wenn Sie diese Option täglich ausführen, können Sie Ihre Sicherungsdateien in einem ununterbrochenen Monat aufbewahren und so den Speicherplatz auf der Festplatte besser verwalten.

Um die 1. oder 15. Datei zu behalten, können Sie sie entweder in einem anderen Verzeichnis speichern oder den Befehl find mit der Option -not -name aktualisieren.


0

Sie können versuchen, wie das Datum folgendermaßen funktioniert:

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

Ich denke also, dass basierend auf dem aktuellen letzten Monat (nicht aktuell, wenn dies März ist) die Anzahl der Tage des letzten Monats gegenüber dem aktuellen Monat verringert wird.

Sie können die folgende Syntax verwenden, um Dateien zu löschen, die älter als einige Tage sind (im Beispiel unter 31 Tagen). Eine Zeile, um das Problem zu lösen (dies ist ein einfacher Ansatz).

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

Für eine detailliertere Vorgehensweise können Sie auch Folgendes tun: 1. Ermitteln der Anzahl der Tage für den aktuellen Monat:

cal $(date +%m) $(date +%y) | egrep -v "$(date +%y)|Su" | xargs | awk '{print $NF}'
  1. Anzahl der Tage des letzten Monats ermitteln:

    Echo "$ (cal $ (Datum +% m) $ (Datum +% y) | egrep -v" $ (Datum +% y) | Su "| xargs | awk '{print $ NF}') -" $ ( cal $ (Datum -d "vor +1 Monat" +% m) $ (Datum +% y) | egrep -v "$ (Datum +% y) | Su" | xargs | awk '{print $ NF}') | bc

  2. Nun finden wir den Unterschied zwischen diesen beiden Monaten:

    Echo "$ (cal $ (Datum +% m) $ (Datum +% y) | egrep -v" $ (Datum +% y) | Su "| xargs | awk '{print $ NF}') -" $ ( cal $ (Datum -d "vor +1 Monat" +% m) $ (Datum +% y) | egrep -v "$ (Datum +% y) | Su" | xargs | awk '{print $ NF}') | bc

Weisen Sie diesen 3 Schritten nun einige Variablen zu. Schritt 1 Variablenname: FCM Schritt 2 Variablenname: FLM Schritt 3 Variablenname: 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)

Überprüfen Sie, ob $ DCL gleich 0 (Null) ist, und löschen Sie basierend auf der Differenz zwischen $ FCM und $ 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

Sie können auch eine Variable zu "/ path / to / folde / with / arhives /" hinzufügen.

Fazit: Wenn Sie Dateien löschen möchten, die älter als genau ein Monat sind, müssen Sie die genaue Anzahl der Tage anpassen, wenn Sie den Befehl "date" und "+1 month ago" verwenden.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.