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


22

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

例えば

現在の日付がの場合March 28th、1か月前はでなければなりませんがFebruary 28th、そうなったらどうなりますMarch 30thか?

シナリオ

私は毎日いくつかのファイルをバックアップしたいのですが、スクリプトは現在の日付内でこのファイルをの$(date +%Y%m%d)ような形式で保存20150603_bckp.tar.gzし、次の月が来ると、1番目と15番目のファイルを除く1ヶ月前にすべてのファイルを削除します私の状態:

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日目のファイルは削除されますか?

ほのめかしたことを願っています。


1
私は、この正確な理由のために3月30日にここにいるか分からないだろう
user7203

回答:


24

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

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

単位のファズは、相対的なアイテムに問題を引き起こす可能性があります。たとえば、2003-07-31 -1 month2003-06-31は無効な日付であるため、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前に環境変数をに設定して世界時を採用するのが賢明です。


ここ、特に2月の状況には疑問があります... 3月29、30、または31の場合、現在の月が存在しない場合、過去1か月の次の数がかかる可能性があるため、この3つの状況では3月1日?あなたが言ったように、3月29、30、31、そして3月1、2、3の場合、4月1日は3月4日になります。 ?
タコミ

4月1日の1か月前は3月1日、3月1日の1か月前は2月1日です。これらは問題ではありません。問題は、4月31日が存在しないため、5月31日の1か月前が5月1日であることです。現在の日付ではなく、1か月前の日付の日番号を確認する必要があります。
リチ

2
ど!ある月の特定の日の「1か月前」が同じ月になる可能性があるという事実は、date実装に期待することではありません。私の本では、これは意味的に反直感的です。-それを指摘してくれてありがとう、知っておくといい。
ジャニス

2

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

たとえば、次のコマンドを使用して、30日より古いすべてのファイルを削除できます。

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

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

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


0

次の方法で、日付がどのように機能するかを確認できます。

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 month ago" +%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 month ago" +%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 month ago」を使用している場合は、正確な日数を調整する必要があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.