2008-10-22 20 views
6

Cách thanh lịch nhất để tính toán ngày làm việc trước đó trong kịch bản lệnh shell ksh là gì?Làm cách nào để tính toán ngày làm việc trước đó trong tập lệnh trình bao ksh?

Những gì tôi nhận được cho đến bây giờ là:

#!/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 

Làm thế nào để làm cho $ {} DAY_DIFF biến được truyền đi như giá trị và không phải là chuỗi?

+0

Bạn đã bỏ qua thứ bảy ... –

+0

Scratch đó - nó được bao phủ bởi các thiết lập mặc định của DAY_DIFF = 1 trước khi trường hợp ... Nó sẽ được rõ ràng hơn nếu mặc định là trong trường hợp. –

+0

Câu trả lời trực tiếp cho câu hỏi 'Làm thế nào để ...' là: đặt một trích dẫn trước và một sau $ {DAY_DIFF} trong lệnh perl. –

Trả lời

0

Vâng, nếu chạy Perl được tính là một phần của tập lệnh, hãy phát triển câu trả lời trong Perl. Câu hỏi tiếp theo là - điều gì định nghĩa một ngày làm việc? Bạn có phải là cửa hàng/cửa hàng mở cửa vào Chủ nhật không? Ngày thứ bảy? Hoặc một doanh nghiệp 9-5 từ thứ Hai đến thứ Sáu? Điều gì về ngày lễ?

Giả sử bạn đang suy nghĩ từ thứ Hai đến thứ Sáu và ngày lễ tạm thời không quan trọng, thì bạn có thể sử dụng thuật toán trong Perl ghi chú rằng wday sẽ là 0 vào Chủ nhật đến 6 ngày thứ Bảy, và do đó, nếu wday là 1, bạn cần trừ 3 * 86400 từ thời gian(); nếu wday là 0, bạn cần trừ 2 * 86400; và nếu wday là 6, bạn cần phải trừ đi 1 * 86400. Đó là những gì bạn đã có trong những thứ vỏ Korn - chỉ cần làm điều đó trong Perl thay vì:

#!/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)); 

này giả sử bạn có các mô-đun POSIX; nếu không, sau đó bạn sẽ cần phải làm khoảng cùng một printf() như bạn đã sử dụng. Tôi cũng sử dụng định dạng ISO 8601 cho các ngày theo sở thích (cũng được sử dụng bởi XSD và SQL) - do đó định dạng được minh họa.

+0

'Ngày làm việc' là thuật ngữ chuẩn không bao gồm Sat và Sun. – jwg

2

Đây là giải pháp không sử dụng Perl. Nó hoạt động cả với 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 
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) 
0

này nên làm việc cho Solaris và Linux. Nó thực sự phức tạp trên Unix mà bạn không thể sử dụng cùng một đối số dòng lệnh trên tất cả các dẫn xuất Unix.

Trên Linux, bạn có thể sử dụng date -d '-d24 hour ago' để có được ngày cuối cùng trên Solaris TZ=CET+24 date. Tôi đoán UNIX khác hoạt động theo cách tương tự như 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 
Các vấn đề liên quan