1

我正在尝试以某种格式查找日期,我之前使用 perl( strftime) 做过,但那次我提到了静态时间,这次我需要一个变量 $CURRENT_DAY 这里。

下面是问题,当将CURRENT_DAYby usingDAYHOUR=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
4

4 回答 4

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 小时将无法正确计算夏令时更改。查看此常见问题解答

于 2012-12-20T13:54:29.340 回答
3

您可以在@ARGV 中将它们作为参数传递:

$ dd_seconds_ago () { perl -MPOSIX -e 'print strftime q(%d), localtime(time - shift)' "$@"; }

$ DD=$(dd_seconds_ago 86400)

在没有参数的情况下,在上述上下文中,shift转移@ARGV,这对于像这样的 shell 单行来说很方便

于 2012-12-20T14:07:01.963 回答
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
于 2012-12-20T18:24:24.097 回答
0

I am assuming you want to pass the number of days in the past in the shell variable DAY and that you want the answer in the shell variable DD

So if it is the 20th of the month and the DAY is 1, then DD should be set to 19

You could modify your Perl command as follows:

 DD=`perl -e 'use POSIX; print strftime "%d", localtime( time - ($ENV{DAY}* 86400))';

Alternatively, you could use the GNU date command that is widely available

 DD=`date -d "$DAY days ago" +%d`

Using date is probably better at dealing with leap days, etc

于 2012-12-20T13:57:44.197 回答