date命令中的“ 1个月前”选项如何工作?


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日甚至是过去2月的示例时会发生什么?会保留那些文件吗?或删除第一天的文件?

到31日时,将执行净化,因此,如果过去一个月只有30天,这会删除第一天的文件吗?

我希望我能暗示。


1
您不知道我是3月30日在这里的确切原因

Answers:


24

- 1 month将从月份号中减去一个,然后如果结果日期无效(February 30例如,),请对其进行调整以使其有效。那么December 31 - 1 monthDecember 1,没有一天11月和March 31 - 1 monthMarch 3(除非闰年执行)。

这是信息页中Gnu datedate实现该语法的版本)的引文,其中包括一个使算法更健壮的好建议:

单位的绒毛可能导致相关项目出现问题。例如,2003-07-31 -1 month由于2003-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日不存在当前月份,则过去一个月可能需要以下数字,因此在这三种情况下, 3月1日不是吗?因为如果您说的是3月29日,30日,31日,然后是3月1日,2日,3日,那么4月1日将是3月4日,这是因为进行了重组(我不知道是否说得很对),您如何看待?
tachomi

4月1日之前的一个月是3月1日,3月1日之前的一个月是2月1日。这不是问题。问题在于5月31日之前的一个月是5月1日,因为4月31日不存在。您应该检查一个月前日期的天数,而不是当前日期的天数。
rici 2015年

2
h!任何月份中某些特定日期的“一个月前”都可能导致一个月的事实,这并不是我从date实现中期望的结果;在我的书中,这在语义上是违反直觉的。-感谢您指出这一点,很高兴知道。
Janis 2015年

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天)。一线解决的问题(这是一种简单的方法)。

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. 因此,现在我们发现这两个月之间的区别:

    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 /”。

结论:如果要删除早于一个月的文件(正好),并且使用“ date”命令和“ +1 month ago”,则需要调整确切的天数。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.