我试图以某种格式找到日期,我之前用perl(strftime
)完成了,但那次我提到了静态时间,这次我需要一个变量$ CURRENT_DAY。< / p>
下面是问题,当使用CURRENT_DAY
和整数等同DAYHOUR=86400
时,变量给出正确的时间,但是一旦我在语句中放入$CURRENT_DAY
变量,日期不会减少。
$ DAYHOUR=86400
$ DAY=1
$ CURRENT_DAY=`echo $(($DAYHOUR*$DAY))`
$ DD=`perl -e 'use POSIX; print strftime "%d", localtime time - $CURRENT_DAY;'`
$ echo $DD
20
$ DAY=`echo $(($DAY+1))`
$ CURRENT_DAY=`echo $(($DAYHOUR*$DAY))`
$ DD=`perl -e 'use POSIX; print strftime "%d", localtime time - $CURRENT_DAY;'`
$ echo $DD
20
$ DAY=`echo $(($DAY+1))`
$ echo $DAY
3
$ CURRENT_DAY=`echo $(($DAYHOUR*$DAY))`
$ echo $CURRENT_DAY
259200
$ echo `perl -e 'use POSIX; print strftime "%d", localtime time - 259200;'`
17
答案 0 :(得分:4)
您的主要问题是$CURRENT_DAY
是Perl脚本变量。通过将Perl脚本用单引号括起来,shell的同名变量没有可见性。如果你启用了警告(例如-w
),你会看到这个。
有几种方法可以解决您的问题。一种是使用双引号来封装Perl,从而允许shell在运行Perl之前首先扩展其变量的值:
CURRENT_DAY=3
perl -MPOSIX -wle "print strftime qq(%d),localtime time-(86400*$CURRENT_DAY);print $CURRENT_DAY"
17
另一个是:
export CURRENT_DAY=3
perl -MPOSIX -wle 'print strftime qq(%d),localtime time-(86400*$ENV{CURRENT_DAY})'
请注意,从昨天或明天计算的24小时内添加或减去将无法正确计算夏令时的变化。见this faq
答案 1 :(得分:3)
您可以在@ARGV中将它们作为参数传递:
$ dd_seconds_ago () { perl -MPOSIX -e 'print strftime q(%d), localtime(time - shift)' "$@"; }
$ DD=$(dd_seconds_ago 86400)
没有参数,在上面的上下文中,shift
改变了@ARGV,这对于像这样的shell单行来说很方便
答案 2 :(得分:1)
与Perl一样,sh
不会在单引号字符串中进行插值,因此Perl会看到$CURRENT_DAY
而不是实际数字,并且您从未为该Perl变量分配任何内容。你可以切换到双引号字符串。
perl -MPOSIX -e"print strftime '%d', localtime time-$CURRENT_DAY;"
这很好,因为$CURRENT_DAY
是一个数字,但如果你想传递一个任意字符串,你可以使用env var或一个参数。
export CURRENT_DAY
perl -MPOSIX -e'print strftime "%d", localtime time-$ENV{CURRENT_DAY};'
或
perl -MPOSIX -e'print strftime "%d", localtime time-$ARGV[0];' -- "$CURRENT_DAY"
请注意,您的代码有问题。每年有两个小时的代码会给出错误的答案,因为并非所有日子都有86400秒。有些人有82800,有些人有90000.(而且假设闰秒没有考虑因素。)Perl解决方案没有遇到这个问题:
perl -MDateTime -e'print
DateTime->today(time_zone=>"local")
->subtract(days=>$ARGV[0])
->strftime("%d")' -- "$DAY"
或者您可以使用date
。
date -d "$DAY days ago" +%d
答案 3 :(得分:0)
我假设您想要在shell变量DAY
中传递过去的天数,并且您希望在shell变量DD中传递答案
因此,如果它是月份的第20个且DAY
为1,那么DD应该设置为19
您可以按如下方式修改Perl命令:
DD=`perl -e 'use POSIX; print strftime "%d", localtime( time - ($ENV{DAY}* 86400))';
或者,您可以使用广泛可用的GNU date
命令
DD=`date -d "$DAY days ago" +%d`
使用date
可能更好地处理闰日等问题