Mesa de férias

Mesa de férias

Preciso de um script para converter esta lista de feriados em formato de data. Meu arquivo de entrada

MMYYYY CAL_B2K_ID   123456789012345678901234567890  
------ ------------ ------------------------------- 
012016 821          YY      Y      Y      Y      Y  
012016 DC           YY      Y      Y      Y      Y  
022016 DC                Y      Y      Y      Y     
022016 821               Y      Y      Y      Y     
032016 DC               Y      Y      Y      Y      
032016 821              Y      Y      Y      Y      
042016 821           Y      Y      Y      Y         

Agora 123456789012345678901234567890 é como a data quando chega o 0 pela primeira vez, é 10 e então 1 significa 11 e assim por diante. ...

 1 2 3 4 5 6 7 8 9 10 11 12 13 14............

Então eu criei um script onde quer que Y esteja presente, ele é convertido em data, suponha que na primeira linha Y esteja presente em 1, 2,9,6,3,9

No meu script, cortei cada linha da coluna 21-52 e verifiquei se essa coluna é Y, se sim, ela é convertida em data, como se Y estivesse presente na coluna número 23. Então estou subratificando (número da coluna - 20) ele irá me dê 3 E então estou usando o operador concat para marcar a data.

Abaixo está meu roteiro. Mas estou enfrentando um problema quando não há Y em nenhuma coluna, meu var é considerado em branco e o branco também está em condição verdadeira.

var=echo $f1 | cut -c$i
if [[ "$var"='Y' ]] ;

E meu script está abaixo.

 rm f1.txt
 set -x
 while read f1
 do
 for((i=21;i<23;i++));
 do
 var=`echo $f1 | cut -c$i`
 if [[ "$var"='Y' ]] ;
 then
 echo $var
 month=`echo $f1 | cut -c1-2`
 year=`echo $f1 |cut -c3-6`
 date=$(($i-20))
 echo $year"-"$month"-"$date >> f1.txt
 fi
done
done < holiday_india.txt`

Por favor, deixe-me saber o que farei para que, quando não houver nada em var , não caia na condição If true.

O/p deste script é que ele converte todas as colunas de cada linha de 21 a 52 em datas não onde Y está presente.

Espero ter esclarecido agora.

Responder1

Ok, copiei seu script abaixo e corrigi o recuo para facilitar a leitura. (E também mudei os crases $()e removi os nomes de arquivos fixos porque gosto assim.)

while read f1 ; do
    for((i=21;i<23;i++)); do
        var=$(echo $f1 | cut -c$i)
        if [[ "$var"='Y' ]] ; then
            echo $var
            month=$(echo $f1 | cut -c1-2)
            year=$(echo $f1 |cut -c3-6)
            date=$(($i-20))
            echo "$year-$month-$date"
        fi
    done
done

Duas coisas saltam à vista:

if [[ "$var"='Y' ]] ; then

Isso não funciona; precisa de espaços ao redor do sinal de igual. Experimente e veja o que [[ X=Y ]] && echo fooacontece.

Aqui também

var=$(echo $f1 | cut -c$i)

f1contém algo como 012016 821 YY Y Y Y Y, mas como não está entre aspas, ele é expandido e, em seguida, dividido por palavras ao longo dos espaços, após o que echoimprime todas as palavras separadas porsolteiroespaços, resultando em 012016 821 YY Y Y Y Y. Você poderia consertar isso adicionando aspas: echo "$f1" | cut -c$i, mas também há uma substring de comprimento"${f1:N:L}"euda posiçãoN. Porém, ele é indexado em zero, portanto, o intervalo de $iprecisará ser modificado.

Então,

echo "$year-$month-$date"

Isso pode ser alterado para printf "%04d-%02d-%02d\n" "$year" "$month" "$date"garantir que a data seja sempre impressa com dois dígitos e para proteger contra possíveis valores anômalos de $year.

É melhor mover as atribuições de mês e ano para o loop externo, já que elas permanecem as mesmas durante toda a linha.

Agora temos:

while read f1; do
    month="${f1:0:2}"
    year="${f1:2:4}"
    for (( i=20 ; i < 20 + 31 ; i++ )); do
        var="${f1:$i:1}"
        if [[ "$var" = "Y" ]] ; then
            date=$(( $i - 19 ))
            printf "%04d-%02d-%02d\n" "$year" "$month" "$date"
        fi
    done
done

A saída parece correta quando eu a executo com bash holiday.sh < holiday_india.txt:

2016-01-01
2016-01-02
2016-01-09
2016-01-16
2016-01-23
2016-01-30
2016-01-01

É claro que parece que todos os meses dobraram, então a produção também dobrou. Talvez adicione um teste para o conteúdo da segunda coluna ou execute-o com algo assim para verificar apenas as linhas com o ID fornecido:

grep DC holiday_india.txt | bash holiday.sh

(É claro que isso também pularia as linhas do cabeçalho. Ou você poderia verificar se o mês/ano está correto no início da linha.)

Isso foi marcado com ksh, mas usei bash. A cópia de kshI have support , que acho que foi a única sintaxe nova que usei.${foo:N:L}

informação relacionada