Як працює опція "1 місяць тому" в команді date?


22

Я не впевнений, чи отримає це минулу дату протягом поточного дня, чи це займе 30 або 31 день.

напр

Якщо поточна дата є March 28th, 1 місяць тому має бути February 28th, але що станеться, коли це March 30th?

Сценарій

Я хочу створити резервну копію файлів щодня, скрипт збереже ці файли протягом поточної дати у такому $(date +%Y%m%d)форматі, як 20150603_bckp.tar.gz, тоді, коли наступний місяць прийде, видаліть усі ці файли протягом 1 місяця тому, крім файлів 1-го та 15-го, так що це мій стан:

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

Але я хочу знати, що станеться, коли дата буде 30-м, 31-м чи навіть минулим прикладом лютого? Це збереже ці файли? або видалити файли першого дня?

Коли це 31 число, депутація буде виконана, тож якщо за минулий місяць було лише 30 днів, це видалить файл першого дня?

Сподіваюся, я натякнув.


1
Чи не знаєте ви, що я тут 30 березня саме з цієї причини
user7203

Відповіді:


24

- 1 monthвідніме один із числа місяця, а потім, якщо отримана дата не є дійсною ( February 30наприклад,), відрегулюйте її так, щоб вона була дійсною. Так December 31 - 1 monthє December 1, не день у листопаді, а March 31 - 1 monthє March 3(якщо не буде виконано у високосний рік).

Ось цитата на інформаційній сторінці для Gnu date(це dateверсія, яка реалізує цей синтаксис), яка містить гарну пропозицію зробити арифметику більш надійною:

Нечіткість в одиницях може спричинити проблеми з відносними предметами. Наприклад, 2003-07-31 -1 monthможе бути оцінено до 2003-07-01, оскільки 2003-06-31 є недійсною датою. Щоб визначити попередній місяць надійніше, ви можете запитати за місяць до 15 числа поточного місяця. Наприклад:

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

Ще одне попередження, яке також цитується з інформаційної сторінки:

Крім того, будьте обережні, маніпулюючи датами цілодобово, такі як стрибки літнього часу. У кількох випадках вони додавали або віднімали цілих 24 години від годин, тому часто розумно прийняти універсальний час, встановивши TZзмінну середовища, UTC0 перш ніж приступати до календаричних обчислень.


У мене є сумніви в цьому, зокрема в лютневій ситуації ... Коли це 29, 30 або 31 березня, це може мати наступну кількість минулого місяця, якщо поточного не існує, тож у цих трьох ситуаціях це може зайнятись 1 березня ні? Тому що, якщо ви сказали, 29, 30, 31 березня, а потім 1, 2, 3 березня, 1 квітня буде 4 березня через реструктуризацію (я не знаю, чи це добре сказано), яка була зроблена, як ви думаєте ?
tachomi

За місяць до 1 квітня - 1 березня, а місяць - до 1 березня - 1 лютого. Це не проблеми. Проблема полягає в тому, що за місяць до 31 травня це 1 травня, оскільки 31 квітня не існує. Ви повинні перевірити номер дня дати місяця тому, а не день поточної дати.
rici

2
До! Той факт, що «місяць тому» деяких конкретних днів у будь-якому місяці може призвести до того ж місяця, - це нічого, що я очікував від dateвпровадження; у моїй книзі це семантично контр-інтуїтивно зрозуміло. - Дякую, що вказали на це, добре це знати.
Яніс

2

Замість того, щоб покладатися на назви файлів для очищення файлів резервного копіювання, ви б безпечніше покладатися на їх метадані часу.

Наприклад, за допомогою цієї команди можна видалити всі файли старші 30 днів:

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

Як безкоштовний бонус, запуск цього повсякденного дня дозволить вам зберігати резервні файли протягом періоду, що дозволяє краще керувати дисковим простором.

Для збереження 1-го чи 15-го файлів ви можете або зберегти їх в іншій каталозі, або оновити команду find за допомогою параметра -not -name.


0

Ви можете спробувати побачити, як працює дата, наступним чином:

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

Тому я вважаю, що на основі лікувального препарату останній місяць (а не лікувальний, якщо це березень) зменшується кількість днів з останнього місяця від місяця лікування.

Ви можете спробувати наступний синтаксис, щоб видалити файли, старші за певний день (наприклад нижче 31 день). Один рядок для вирішення проблеми (це для простого підходу).

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

Для більш детального підходу ви також можете зробити щось подібне: 1. Знаходження кількості днів на місяць, що лікується:

cal $(date +%m) $(date +%y) | egrep -v "$(date +%y)|Su" | xargs | awk '{print $NF}'
  1. Пошук кількості днів за останній місяць:

    echo "$ (cal $ (дата +% m) $ (дата +% y) | egrep -v" $ (дата +% y) | Su "| xargs | awk '{print $ NF}') -" $ ( cal $ (дата -d "+1 місяць тому" +% m) $ (дата +% y) | egrep -v "$ (дата +% y) | Su" | xargs | awk "{print $ NF} ') | до н.е.

  2. Тож тепер ми знаходимо різницю між цими двома місяцями:

    echo "$ (cal $ (дата +% m) $ (дата +% y) | egrep -v" $ (дата +% y) | Su "| xargs | awk '{print $ NF}') -" $ ( cal $ (дата -d "+1 місяць тому" +% m) $ (дата +% y) | egrep -v "$ (дата +% y) | Su" | xargs | awk "{print $ NF} ') | до н.е.

Тепер давайте призначити деякі змінні цим 3 крокам. Крок 1 Назва змінної: FCM Крок 2 Назва змінної: FLM Крок 3 Змінна 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)

Перевірте, чи дорівнює $ DCL 0 (нуль) та видаліть на основі різниці між $ FCM та $ 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

Ви також можете додати змінну до "/ path / to / folde / with / arhives /".

Висновок: Якщо ви хочете видалити файли, старші одного місяця (рівно), вам потрібно скорегувати точну кількість днів, якщо ви використовуєте команду "дата" та "+1 місяць тому".

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.