web-dev-qa-db-ja.com

dateコマンドの「1か月前」オプションはどのように機能しますか?

これが現在の日付以内に過去の日付を取得するのか、それとも30日または31日しかかからないのかわかりません。

例えば.

現在の日付が_March 28th_の場合、1か月前は_February 28th_でなければなりませんが、_March 30th_になるとどうなりますか?

シナリオ

毎日いくつかのファイルをバックアップしたいのですが、スクリプトはこのファイルを_20150603_bckp.tar.gz_のような$(date +%Y%m%d)形式で現在の日付内に保存し、翌月が来たら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日、または過去2月の例の場合はどうなりますか?それらのファイルを保持しますか?または1日目のファイルを削除しますか?

31日になると浄化が実行されるので、過去1か月が30日しかなかった場合、1日目のファイルが削除されますか?

私はほのめかしたと思います。

23
tachomi

- 1 monthは月数から1を減算し、結果の日付が有効でない場合(たとえば、February 30)、有効になるように調整します。したがって、December 31 - 1 monthDecember 1であり、11月の日ではありません。また、March 31 - 1 monthMarch 3です(うるう年で実行されない限り)。

これは、Gnu date(この構文を実装するdateバージョン)の 情報ページ からの引用です。これには、計算をより堅牢にするための適切な提案が含まれています。

ユニットのファズは、関連アイテムに問題を引き起こす可能性があります。たとえば、2003-06-31は無効な日付であるため、2003-07-31 -1 monthは2003-07-01と評価されます。前の月をより確実に判断するために、当月の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に設定して世界時を採用するのが賢明です。

25
rici

バックアップファイルをパージするためにファイル名に依存する代わりに、それらの時間メタデータに依存する方が安全です。

たとえば、次のコマンドで30日以上経過したすべてのファイルを削除できます。

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

無料のボーナスとして、この毎日を実行すると、バックアップファイルを1か月ごとに維持できるため、ディスク領域の管理が向上します。

1番目または15番目のファイルを保持するには、それらを別のディレクトリに保存するか、-not -nameオプションを指定してfindコマンドを更新します。

2
Bertrand Lupart

次のようにして、日付がどのように機能するかを確認することができます。

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

つまり、先月の現在(3月の場合は現在ではない)に基づいて、現在の月から前の月からの日数を減らすと思います。

次の構文を試して、日数より古いファイルを削除することができます(例では31日以下)。問題を解決するための1行(これは単純なアプローチのためです)。

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 $(date +%m)$(date +%y)| egrep -v" $(date +%y)| Su "| xargs | awk '{print $ NF}')-" $( cal $(date -d "+1か月前" +%m)$(date +%y)| egrep -v "$(date +%y)| Su" | xargs | awk '{print $ NF}') |紀元前

  2. したがって、これらの2か月間の違いがわかります。

    echo "$(cal $(date +%m)$(date +%y)| egrep -v" $(date +%y)| Su "| xargs | awk '{print $ NF}')-" $( cal $(date -d "+1か月前" +%m)$(date +%y)| egrep -v "$(date +%y)| Su" | xargs | awk '{print $ NF}') |紀元前

次に、この3つのステップにいくつかの変数を割り当てます。ステップ1変数名:FCMステップ2変数名:FLMステップ3変数名: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か月以上前のファイルを(正確に)削除する場合、「date」コマンドと「+1か月前」を使用している場合は、正確な日数を調整する必要があります。

0
Mihai M