在shell ksh脚本中计算上一个工作日的最优雅方法是什么?
到目前为止我得到的是:
#!/bin/ksh
set -x
DAY_DIFF=1
case `date '+%a'` in
"Sun")
DAY_DIFF=2
;;
"Mon")
DAY_DIFF=3
;;
esac
PREV_DT=`perl -e '($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime(time()-${DAY_DIFF}*24*60*60);printf "%4d%02d%02d",$year+1900,$mon+1,$mday;'`
echo $PREV_DT
如何将$ {DAY_DIFF}变量作为值而不是字符串传输?
答案 0 :(得分:3)
#!/bin/ksh
# GNU date is a veritable Swiss Army Knife...
((D=$(date +%w)+2))
if [ $D -gt 3 ]; then D=1; fi
PREV_DT=$(date -d "-$D days" +%F)
答案 1 :(得分:2)
这是一个不使用Perl的解决方案。它适用于ksh
和sh
。
#!/bin/ksh
diff=-1
[ `date +%u` == 1 ] && diff=-3
seconds=$((`date +%s` + $diff * 24 * 3600))
format=+%Y-%m-%d
if date --help 2>/dev/null | grep -q -- -d ; then
# GNU date (e.g., Linux)
date -d "1970-01-01 00:00 UTC + $seconds seconds" $format
else
# For BSD date (e.g., Mac OS X)
date -r $seconds $format
fi
答案 2 :(得分:0)
好吧,如果运行Perl算作脚本的一部分,那么在Perl中开发答案。接下来的问题是 - 什么定义了工作日?你是周日营业的商店/商店吗?星期六?或周一至周五9-5的业务?假期怎么样?
假设你想周一到周五,假期暂时不重要,那么你可以在Perl中使用一个算法,它注意周日的星期日到星期六的星期日为0,因此如果星期日是1,你需要减去3 * 86400 from time();如果wday为0,则需要减去2 * 86400;如果wday是6,你需要减去1 * 86400.这就是你在Korn shell中所拥有的东西 - 只需在Perl中进行:
#!/bin/perl -w
use strict;
use POSIX;
use constant SECS_PER_DAY => 24 * 60 * 60;
my(@days) = (2, 3, 1, 1, 1, 1, 1);
my($now) = time;
my($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime($now);
print strftime("%Y-%m-%d\n", localtime($now - $days[$wday] * SECS_PER_DAY));
这假设你有POSIX模块;如果没有,那么你需要做与你使用的大致相同的printf()。我还优先使用ISO 8601格式的日期(也由XSD和SQL使用) - 因此说明的格式。
答案 3 :(得分:0)
这适用于Solaris和Linux。在Unix上实际上很复杂,你不能在所有Unix派生上使用相同的命令行参数。
在Linux上,您可以使用date -d '-d24 hour ago'
来获取最后一天
在Solaris上TZ=CET+24 date
。我猜其他UNIX的工作方式与Solaris相同。
#!/usr/bin/ksh
lbd=5 # last business day (1=Mon, 2=Thu ... 6=Sat, 7=Sun)
lbd_date="" # last business day date
function lbdSunOS
{
typeset back=$1
typeset tz=`date '+%Z'` # timezone
lbd_date=`TZ=${tz}+$back date '+%Y%m%d'`
}
function lbdLinux
{
typeset back=$1
lbd_date=`date -d "-d$back hour ago"`
}
function calcHoursBack
{
typeset lbd=$1
typeset dow=`date '+%u'` # day of the week
if [ $dow -ge $lbd ]
then
return $(((dow-lbd)*24))
else
return $(((dow-lbd+7)*24))
fi
}
# Main
calcHoursBack $lbd
lbd`uname -s` $?
echo $lbd_date