「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(別名FDAATE)をエクスポートする必要はありません。実行中のサブシェルが終了すると、変数は失われます。 . scriptname.

関連情報