6

シェル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} 変数を文字列ではなく値として送信するにはどうすればよいですか?

4

4 に答える 4

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)
于 2009-09-21T18:13:10.113 に答える
2

これはPerlを使用しないソリューションです。との両方で動作kshshます。

#!/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
于 2008-10-23T10:16:33.863 に答える
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
于 2009-12-05T14:50:41.090 に答える
0

Perl の実行がスクリプトの一部としてカウントされる場合は、Perl で回答を作成します。次の質問は、営業日を定義するものは何ですか? あなたは日曜日に開いているお店/店ですか? 土曜日?または、月曜から金曜までの 9 時から 5 時までのビジネスですか? 休日はどうですか?

月曜日から金曜日までと休日が一時的に重要ではないと考えていると仮定すると、日曜日の wday が 0 から土曜日の 6 になることに注意する Perl のアルゴリズムを使用できます。したがって、wday が 1 の場合、3 * 86400 を引く必要があります。時間から(); wday が 0 の場合、2 * 86400 を引く必要があります。wday が 6 の場合は、1 * 86400 を引く必要があります。これは、Korn シェルのもので得られたものです。代わりに 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 でも使用されます)。

于 2008-10-22T03:49:57.047 に答える