Come funziona l'opzione "1 mese fa" nel comando data?


22

Non sono sicuro se questo abbia la data passata entro il giorno corrente o se ci vogliono solo 30 o 31 giorni.

per esempio

Se la data corrente è March 28th, 1 mese fa deve essere February 28th, ma cosa succede quando è March 30th?

Scenario

Voglio eseguire il backup di alcuni file ogni giorno, lo script salverà questi file entro la data corrente con il $(date +%Y%m%d)formato, come 20150603_bckp.tar.gz, quindi, quando arriva il mese successivo, rimuovi tutti quei file entro 1 mese fa tranne i file del 1 ° e del 15 °, quindi questo è le mie condizioni:

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

Ma voglio sapere, cosa succederà quando la data è il 30, il 31 o addirittura l'esempio dello scorso febbraio? Manterrà quei file? o rimuovere i file del 1 ° giorno?

Quando sarà il 31, verrà eseguita la depurazione, quindi se il mese scorso ha avuto solo 30 giorni, questo rimuoverà il primo file del giorno?

Spero di aver accennato.


1
Non sapresti che sono qui il 30 marzo per questo motivo esatto
user7203

Risposte:


24

- 1 monthsottrarrà uno dal numero del mese, quindi se la data risultante non è valida ( February 30ad esempio), la regolerà in modo che sia valida. Così December 31 - 1 monthè December 1, non un giorno a novembre, ed March 31 - 1 monthè March 3(se non eseguito in un anno bisestile).

Ecco la citazione dalla pagina informativa di Gnu date(che è la dateversione che implementa questa sintassi), che include un buon suggerimento per rendere l'aritmetica più solida:

Il fuzz in unità può causare problemi con gli articoli relativi. Ad esempio, 2003-07-31 -1 monthpotrebbe valutare 2003-01-01, perché 2003-06-31 non è una data valida. Per determinare il mese precedente in modo più affidabile, è possibile richiedere il mese prima del 15 del mese corrente. Per esempio:

    $ 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 altro avvertimento, citato anche dalla pagina delle informazioni:

Inoltre, prestare attenzione quando si manipolano le date ininterrottamente, come i cambiamenti dell'ora legale. In alcuni casi questi hanno aggiunto o sottratto fino a 24 ore dall'orologio, quindi è spesso saggio adottare il tempo universale impostando la TZvariabile di ambiente su UTC0 prima di intraprendere calcoli calendari.


Ho un dubbio qui, in particolare nella situazione di febbraio ... Quando è il 29, 30 o 31 marzo potrebbe essere necessario il seguente numero del mese scorso se quello attuale non esiste, quindi in queste tre situazioni potrebbe essere necessario 1 marzo no? Perché se il 29, 30, 31 marzo e poi il 1, 2, 3 marzo, come hai detto, il 1 ° aprile sarà il 4 marzo a causa della ristrutturazione (non so se sia ben detto) che è stata fatta, cosa ne pensi ?
Tachomi,

Un mese prima del 1 ° aprile è il 1 ° marzo e un mese prima del 1 ° marzo è il 1 ° febbraio. Questi non sono problemi. Il problema è che un mese prima del 31 maggio è il 1 maggio perché il 31 aprile non esiste. È necessario controllare il numero del giorno della data di un mese fa, non il giorno della data corrente.
rici,

2
Doh! Il fatto che "un mese fa" di alcuni giorni specifici in qualsiasi mese possa comportare lo stesso mese non è nulla che mi aspetterei da dateun'implementazione; nel mio libro è semanticamente intuitivo. - Grazie per averlo sottolineato, è bello saperlo.
Janis,

2

Invece di affidarti a nomi di file per eliminare i tuoi file di backup, saresti più sicuro affidarti ai loro metadati temporali.

Ad esempio è possibile eliminare tutti i file più vecchi di 30 giorni con questo comando:

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

Come bonus gratuito, eseguirlo ogni giorno ti consentirà di conservare i tuoi file di backup su un mese corrente, consentendo una migliore gestione dello spazio su disco.

Per conservare i file 1o o 15o, è possibile archiviarli in un'altra directory, oppure aggiornare il comando find con l'opzione -not -name.


0

Puoi provare a vedere come funziona la data nel modo seguente:

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

Quindi penso che in base al curent del mese scorso (non curent, se quello è marzo), diminuisce il numero di giorni dall'ultimo mese dal mese corrente.

È possibile provare la sintassi seguente per eliminare i file più vecchi di un numero di giorni (nell'esempio di seguito 31 giorni). Una riga per risolvere il problema (questo è per un approccio semplice).

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

Per un approccio più dettagliato potresti anche fare qualcosa del genere: 1. Trovare il numero di giorni per il mese corrente:

cal $(date +%m) $(date +%y) | egrep -v "$(date +%y)|Su" | xargs | awk '{print $NF}'
  1. Trovare il numero di giorni per l'ultimo mese:

    echo "$ (cal $ (data +% m) $ (data +% y) | egrep -v" $ (data +% y) | Su "| xargs | awk '{print $ NF}') -" $ ( cal $ (data -d "+1 mese fa" +% m) $ (data +% y) | egrep -v "$ (data +% y) | Su" | xargs | awk '{print $ NF}') | avanti Cristo

  2. Quindi ora troviamo la differenza tra quei due mesi:

    echo "$ (cal $ (data +% m) $ (data +% y) | egrep -v" $ (data +% y) | Su "| xargs | awk '{print $ NF}') -" $ ( cal $ (data -d "+1 mese fa" +% m) $ (data +% y) | egrep -v "$ (data +% y) | Su" | xargs | awk '{print $ NF}') | avanti Cristo

Ora consente di assegnare alcune variabili a questi 3 passaggi. Passaggio 1 Nome variabile: FCM Passaggio 2 Nome variabile: FLM Passaggio 3 NAme variabile: 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)

Verifica se $ DCL è uguale a 0 (zero) ed elimina in base alla differenza tra $ FCM e $ 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

Puoi anche aggiungere una variabile a "/ path / to / folde / with / arhives /".

Conclusione: se si desidera eliminare i file più vecchi di un mese (esattamente), è necessario modificare il numero esatto di giorni, se si utilizza il comando "data" e "+1 mese fa".

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.