Como obter os últimos cinco dias úteis em um script de shell Unix usando um loop 'for'?

1

O seguinte script:

BUSSINESS_DATE='date -d "-2 day" +"%Y%m%d"'
for (( c=0; c<5 ; 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

não está dando saída adequada. Alguém pode me aconselhar - o que está errado e como corrigi-lo?

    
por srikanth 05.11.2015 / 09:15

4 respostas

1

Se você quer apenas 5 dias úteis antes de hoje, tente:

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

Para qualquer N dias antes de hoje:

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
    
por 05.11.2015 / 11:37
0

Quando aplico essas alterações ao seu script:

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)

Eu recebo esta saída:

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

É isso que você está procurando?

    
por 05.11.2015 / 09:38
0

Uau, isso é extraordinariamente ilegível. Tente usar uma correção de caso em vez de if / then / elif / else / fi.

por exemplo,

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

Observe que reformatá-lo para torná-lo mais legível também torna óbvio que há um espaço ausente entre day e -2day no caso 0 . facilmente corrigido.

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

BTW, se eu fosse você, deixaria os nomes das variáveis muito mais curtos (e talvez adicionaria um comentário antes do primeiro uso deles para indicar claramente quais são) para tornar o script ainda mais legível, embrulho.

por exemplo. alterar BUSINESS_DATE para BD

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

FILE_DT_TMP pode ser renomeado para FDT e FILE_DT para FD ou FDATE .

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

Há uma vantagem real em reformatar códigos como esse - quando as coisas que deveriam estar alinhadas não se alinham, elas se destacam como um sinal de néon piscando.

Outras notas:

  1. Eu mudei todos os backticks para $() . os backticks são obsoletos e bagunçam as citações, não os use.

  2. Não há necessidade de exportar FILE_DT (também conhecido como FDATE) - a variável será perdida quando o sub-shell que está sendo executado terminar. Ele só será definido no shell pai se você gerar o script com . scriptname .

por 05.11.2015 / 09:56
0

Eu entendo que você realmente deseja N dias listados em vez dos cinco codificados que você mostrou na sua pergunta. Aqui está uma solução bash que atenderá a esse requisito:

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

Saída para n=5 , em 5 de novembro de 2015

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
    
por 05.11.2015 / 12:24