`for` 루프를 사용하여 Unix 쉘 스크립트에서 마지막 'N' 영업일을 얻는 방법은 무엇입니까?

`for` 루프를 사용하여 Unix 쉘 스크립트에서 마지막 'N' 영업일을 얻는 방법은 무엇입니까?

다음 스크립트:

N=5
BUSINESS_DATE=`date -d "-2 day" +"%Y%m%d"`
for (( c=0; c<N ; c++ ))
do
    WEEKDAY=`date --date="$BUSINESS_DATE -$c day" +%w`

    if [ $WEEKDAY == "0" ]
    then
        FILE_DT_TMP=`date --date="$BUSINESS_DATE -$c day-2day" +%Y%m%d`;
    elif [ $WEEKDAY == "6" ]
    then
        FILE_DT_TMP=`date --date="$BUSINESS_DATE -$c day -2day" +%Y%m%d`;
    elif [ $WEEKDAY == "5" ]
    then
        FILE_DT_TMP=`date --date="$BUSINESS_DATE -$c day -2day" +%Y%m%d`;
    elif [ $WEEKDAY == "4" ]
    then
        FILE_DT_TMP=`date --date="$BUSINESS_DATE -$c day -2day" +%Y%m%d`;
    elif [ $WEEKDAY == "3" ]
    then
        FILE_DT_TMP=`date --date="$BUSINESS_DATE -$c day -2day" +%Y%m%d`;
    elif [ $WEEKDAY == "2" ]
    then
        FILE_DT_TMP=`date --date="$BUSINESS_DATE -$c day -2day" +%Y%m%d`;
    elif [ $WEEKDAY == "1" ]
    then
        FILE_DT_TMP=`date --date="$BUSINESS_DATE -$c day -2day" +%Y%m%d`;
    else
        FILE_DT_TMP=`date --date="$BUSINESS_DATE -$c day" +%Y%m%d`
    fi
    export FILE_DT=$FILE_DT_TMP
    echo "File date is :$FILE_DT"
done

제대로 된 출력을 제공하지 않습니다. 누구든지 나에게 조언을 해줄 수 있습니까? 무엇이 잘못되었으며 어떻게 해결합니까?

답변1

오늘까지 영업일 기준 5일만 남았으면 다음을 시도해 보세요.

for d in Mon Tue Wed Thu Fri
do
    date +%Y%m%d -d "last $d"
done | sort

오늘 이전 N일 동안:

N=10
for i in $(seq $(($N + $N / 5 * 2)) -1 1)
do
    [ `date --date="-$i day" +%u` -le 5 ] &&
       date -d "-$i day" +"File date is : %Y%m%d"
done

답변2

귀하의 질문에 하드코딩된 5일이 아닌 N일을 실제로 나열하기를 원하신다는 점을 이해합니다. bash이 요구 사항을 해결하는 솔루션 은 다음과 같습니다 .

n=5
today=$(date +'%Y-%m-%d')
for ((d=1; n>0; d++))
do
    # Adjust this next line to get the date format you require, e.g. +'%Y%m%d'
    date=$(date --date "$today -$d day")
    nday=$(date --date "$today -$d day" +'%w')
    if [[ nday > 0 && nday < 6 ]]
    then
        # Adjust this next line to output whatever you really need
        echo "n=$n, d=$d, nday=$nday, date=$date: WEEKDAY"
        ((n--))
    fi
done

에 대한 출력 n=5, 2015년 11월 5일 실행

n=5, d=1, nday=3, date=Wed,  4 Nov 2015 00:00:00: WEEKDAY
n=4, d=2, nday=2, date=Tue,  3 Nov 2015 00:00:00: WEEKDAY
n=3, d=3, nday=1, date=Mon,  2 Nov 2015 00:00:00: WEEKDAY
n=2, d=6, nday=5, date=Fri, 30 Oct 2015 00:00:00: WEEKDAY
n=1, d=7, nday=4, date=Thu, 29 Oct 2015 00:00:00: WEEKDAY

답변3

이러한 변경 사항을 스크립트에 적용하면 다음과 같습니다.

1c1
< BUSSINESS_DATE=date -d "-2 day" +"%Y%m%d"
---
> BUSSINESS_DATE=$(date -d "-2 day" +"%Y%m%d")
5c5
<     WEEKDAY=date --date="$BUSSINESS_DATE -$c day" +%w
---
>     WEEKDAY=$(date --date="$BUSSINESS_DATE -$c day" +%w)

나는 다음과 같은 결과를 얻습니다.

File date is :20151101
File date is :20151031
File date is :20151030
File date is :20151029
File date is :20151028

그것이 당신이 찾고 있는 것인가요?

답변4

와, 정말 읽기 힘든 내용이네요. if/then/elif/else/fi 대신에 Case문을 사용해 보세요.

예를 들어

BUSSINESS_DATE=$(date -d "-2 day" +"%Y%m%d")
for (( c=0; c<5 ; c++ )) ; do
    WEEKDAY=$(date --date="$BUSSINESS_DATE -$c day" +%w)

    case "$WEEKDAY" in
        0) FILE_DT_TMP=$(date --date="$BUSSINESS_DATE -$c day-2day" +%Y%m%d) ;;
        6) FILE_DT_TMP=$(date --date="$BUSSINESS_DATE -$c day -2day" +%Y%m%d) ;;
        5) FILE_DT_TMP=$(date --date="$BUSSINESS_DATE -$c day -2day" +%Y%m%d) ;;
        4) FILE_DT_TMP=$(date --date="$BUSSINESS_DATE -$c day -2day" +%Y%m%d) ;;
        3) FILE_DT_TMP=$(date --date="$BUSSINESS_DATE -$c day -2day" +%Y%m%d) ;;
        2) FILE_DT_TMP=$(date --date="$BUSSINESS_DATE -$c day -2day" +%Y%m%d) ;;
        1) FILE_DT_TMP=$(date --date="$BUSSINESS_DATE -$c day -2day" +%Y%m%d) ;;
        *) FILE_DT_TMP=$(date --date="$BUSSINESS_DATE -$c day" +%Y%m%d) ;;
    esac    

    export FILE_DT=$FILE_DT_TMP
    echo "File date is :$FILE_DT"
done

day더 쉽게 읽을 수 있도록 형식을 다시 지정하면 케이스 사이 와 케이스 -2day에 공백이 누락된 것이 분명해집니다 0. 쉽게 고정.

    0) FILE_DT_TMP=$(date --date="$BUSSINESS_DATE -$c day-2 day" +%Y%m%d) ;;

그런데, 제가 당신이라면 줄 바꿈을 피함으로써 스크립트를 훨씬 더 읽기 쉽게 만들기 위해 변수 이름을 훨씬 짧게 만들 것입니다(그리고 변수 이름을 처음 사용하기 전에 변수 이름을 명확하게 설명하기 위해 주석을 추가할 수도 있습니다).

예: BUSINESS_DATE를 BD로 변경

# BD is Business Date
BD=$(date -d "-2 day" +"%Y%m%d")

FILE_DT_TMPFDT, 및 또는 FILE_DT로 이름을 바꿀 수 있습니다 .FDFDATE

BD=$(date -d "-2 day" +"%Y%m%d")
for (( c=0; c<5 ; c++ )) ; do
    WEEKDAY=$(date --date="$BD -$c day" +%w)

    case "$WEEKDAY" in
        0) FDT=$(date --date="$BD -$c day -2day" +%Y%m%d) ;;
        6) FDT=$(date --date="$BD -$c day -2day" +%Y%m%d) ;;
        5) FDT=$(date --date="$BD -$c day -2day" +%Y%m%d) ;;
        4) FDT=$(date --date="$BD -$c day -2day" +%Y%m%d) ;;
        3) FDT=$(date --date="$BD -$c day -2day" +%Y%m%d) ;;
        2) FDT=$(date --date="$BD -$c day -2day" +%Y%m%d) ;;
        1) FDT=$(date --date="$BD -$c day -2day" +%Y%m%d) ;;
        *) FDT=$(date --date="$BD -$c day" +%Y%m%d) ;;
    esac    

    FDATE="$FDT"
    echo "File date is : $FDATE""
done

이와 같이 코드를 다시 포맷하면 실질적인 이점이 있습니다. 정렬되어야 하는 항목이 정렬되지 않으면 깜박이는 네온 사인처럼 눈에 띕니다.

기타 참고사항:

  1. 모든 백틱을 $(). 백틱은 더 이상 사용되지 않으며 인용을 엉망으로 만듭니다. 사용하지 마세요.

  2. FILE_DT(일명 FDATE)를 내보낼 필요가 없습니다. 실행 중인 하위 셸이 종료되면 변수가 손실됩니다. .. scriptname

관련 정보