Mesa navideña

Mesa navideña

Necesito un script para convertir esta lista de días festivos al formato de fecha. Mi archivo 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         

Ahora 123456789012345678901234567890 es como la fecha cuando la primera vez que llega 0 es 10 y luego 1 significa 11 y así sucesivamente. ...

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

Así que he creado un script donde siempre que Y esté presente, se convierte en fecha, supongamos que en la primera línea Y está presente en 1, 2,9,6,3,9.

En mi secuencia de comandos, corté cada línea de las columnas 21 a 52 y verifiqué si esa columna es Y; en caso afirmativo, se convierte en fecha como si Y estuviera presente en la columna número 23. Luego estoy subrando (número de columna - 20). dame 3 Y luego estoy usando el operador concat para hacer la fecha.

A continuación se muestra mi guión. Pero tengo un problema cuando no hay Y debajo de ninguna columna, mi var está en blanco y el espacio en blanco también se encuentra en la condición verdadera.

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

Y mi guión está debajo.

 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, déjeme saber qué haré para que cuando no haya nada en var, no se cumpla la condición If true.

La desventaja de este script es que convierte todas las columnas de cada línea del 21 al 52 en una fecha, no donde Y está presente.

Espero aclararlo ahora.

Respuesta1

Bien, copié el script a continuación y arreglé la sangría para que me resulte un poco más fácil de leer. (Y también cambié las comillas invertidas $()y eliminé los nombres de archivos fijos porque me gusta así).

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

Saltan dos cosas:

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

Esto no funciona; necesita espacios alrededor del signo igual. Pruebe y vea qué [[ X=Y ]] && echo foofunciona.

También aquí

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

f1contiene algo como 012016 821 YY Y Y Y Y, pero como no está entre comillas, se expande, luego se divide la palabra a lo largo de los espacios, después de lo cual echose imprimen todas las palabras separadas porsolteroespacios, lo que resulta en 012016 821 YY Y Y Y Y. Podrías solucionarlo agregando las comillas: echo "$f1" | cut -c$i, pero también hay que tomar una subcadena de longitud"${f1:N:L}"ldesde la posiciónnorte. Sin embargo, está indexado a cero, por lo que $iserá necesario modificar el rango de.

Entonces,

echo "$year-$month-$date"

Esto podría cambiarse para printf "%04d-%02d-%02d\n" "$year" "$month" "$date"garantizar que la fecha siempre se imprima con dos dígitos y para proteger contra posibles valores anómalos de $year.

También podría mover las asignaciones de mes y año al bucle exterior, ya que permanecen iguales para toda la línea.

Ahora tenemos:

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

El resultado parece correcto cuando lo ejecuto con 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

Por supuesto, parece que todos los meses se han duplicado, por lo que la producción también se duplica. Quizás agregue una prueba para el contenido de la segunda columna o ejecútela con algo como esto para verificar solo las líneas con la identificación dada:

grep DC holiday_india.txt | bash holiday.sh

(Esto, por supuesto, también omitiría las líneas del encabezado. O podría verificar que el mes/año esté correcto al comienzo de la línea).

Esto fue etiquetado con ksh, pero usé bash. La copia de kshI havesupports , que creo que fue la única sintaxis nueva que utilicé.${foo:N:L}

información relacionada