我正在创建一个脚本,用于收集上个月用于报告的信息:
到目前为止我有以下变量:
#I used an array to get the previous month.
set -A months Dec Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov
x=`date +%m`
y=`expr $x - 1`
year=`date +%Y`
month=`perl -MPOSIX=strftime -le '@t = localtime; $t[3] = 1; $t[4]--;print strftime("%m", @t)'`
month_abv=`echo ${months[$y]}`
可变输出:
year=2017
month=04
month_abv=Apr
我现在所需要的只是上个月的最后一天。
答案1
您可以使用 GNU 计算本月第一天之前的一天date
:
date -d "$(date +"%Y-%m-01") - 1 day" +"%F"
或使用dateutils
的dateadd
:
dateadd "$(date +"%Y-%m-01")" "-1d"
或者有点棘手的dateutils
用法。舍入至第 31 个月的最后一天。 (记录下来的行为即使在少于 31 天的几个月内也有效。)
$ dateround --next today -31d
2017-04-30
$ dateround --next "2016-03-10" -31d
2016-02-29
答案2
我获取上个月最后一天的方法是:
cal $month $year | awk 'NF {DAYS = $NF}; END {print DAYS}'
使用可变占位符,我可以获得前几个月的日历并打印该月的最后一天:
cal 04 2017 | awk 'NF {DAYS = $NF}; END {print DAYS}'
输出:
30
如果有更简单或更短的方法,我愿意接受所有建议。
答案3
尝试:
eval "$(
LC_ALL=C perl -MPOSIX -le '
@t = localtime;
$t[3]=0; # set day to 0 (day before the first)
print strftime q(year=%Y month=%m day=%d month_abv="%b"), @t'
)"
perl
构造一些 shell 代码(如year=2017 month=04 day=30 month_abv="Apr"
),然后我们eval
将其放入当前 shell(假设是 POSIX shell)。
LC_ALL=C
是强制month_abv为英语,无论区域设置如何。如果您希望它位于用户的区域设置中,请将其删除。
这个day=0
技巧适用于strftime()
GNU、FreeBSD 和 Solaris,但我不知道它在这些之外的可移植性如何。
为了得到第一的上个月的一天,替换$t[3]=0
为$t[3]=1; $t[4]--
即使在一月运行对我来说也有效的,但同样,我不确定它的便携性如何。
答案4
要查找上个月,请按照以下步骤操作:
date -d "-1 months" +%Y/%-m/%-d
这会给你:2018/2/22
while it is 2018/3/22
.
date -d "-1 days" +%Y/%-m/%-d
会给你:2018/3/21
您可以添加或减少任意月份或天数。如果减去足够的月份,它将转到去年。