optimizing-shell-scripts

En esta labor, muchas de las veces los requerimientos del cliente, son más que una oportunidad para desarrollar nuestra habilidad como Administradores.

En esta ocasión quiero compartir un requerimiento, a simple vista sencillo, pero que  representó un buen reto para lograrlo.

El cliente solicitó lo siguiente:

Hola Alex:

Por favor tu apoyo para localizar ASAP los archivos de la lista anexa.

Si notas son del Q3 y Q4 de 2012. Podrías copiarlos al PRDAPP03:/home/operator/Test/, y una vez copiados cambiarles el nombre, adelantándolos un segundo a su hora de captura; me explico, si uno tiene el segundo 14, cambiarlo al segundo 15. Por Ejm:

Antes: 286930102012125951MACL730528HDFRLS05.P7M.1974C7

Después: 286930102012125952MACL730528HDFRLS05.P7M.1974C7

Gracias por el apoyo y saludos Alex.

Nota: El nombre de los archivos mencionados se genera conforme los campos

ID Captura | Fecha | Hora | CURP  Capturista | Archivo | Peso Hexadecimal del archivo

2869|30 10 2012|12 59 51|MACL730528HDFRLS05|. P7M .|1974C7

El lote de archivos, generalmente, no corresponden a un mismo ID de Captura, fecha ú hora; ya que requieren la búsqueda para poder re-procesarlos, debido a algún error en el procesamiento de estos mismos. En este caso, la lista era de más de 65,000 archivos a los que había que modificar un segundo más a su hora de captura.

Conforme mencionaba en un post anterior y fiel a Las Tres Leyes del SysAdmin, hay que explotar las capacidades de scripting para automátizar lo más posible esta tarea y terminarla lo más rápido posible.

2

Tomamos unos cuantos archivos, para prueba del script

prdapp03:/home/operator/test # ls | head -6
021215102012161427MEBC760830MDFNSR04.P7M.15EC4C
028811102012133833GUMH600228HGTTDP02.P7M.11CC90
033406112012104802HEZO860316HGTRVC06.P7M.131DC8
037531102012151650CAJL850805HGTHMS07.P7M.1AA43C
038315102012092333LUMN850419MQTNRN05.P7M.15A2C8
045913092012153205AEAF860124MGTRRR06.P7M.19FCB0
prdapp03:/home/operator/test #

Para obtener la hora de cada archivo, con AWK utilizamos los carácteres alfabeticos como primer delimitador; como segundo delimitador utilizamos el año (2012) :

prdapp03:/home/operator/test # for i in $(ls | head -6); do echo "$i | awk -F'[A-Z]' '{ print $1 }' | awk -F'2012' '{ print $2 }'); done
161427
133833
104802
151650
092333
153205
prdapp03:/home/operator/test #

Para adelantar un segundo, solamente se lo sumamos, enviando esta salida más uno a bc y comparándola con la hora original, para validar que la operación sea correcta:

prdapp03:/home/operator/test # for i in $(ls | head -6); do date1=$(echo "$i" | awk -F'[A-Z]' '{ print $1 }' | awk -F'2012' '{ print $2 }'); date2=$(echo $(echo "$i" | awk -F'[A-Z]' '{ print $1 }' | awk -F'2012' '{ print $2 }')+1 | bc); echo "$date1 : $date2"; done
161427 : 161428
133833 : 133834
104802 : 104803
151650 : 151651
092333 : 092334
153205 : 153206
prdapp03:/home/operator/test #

Comprobado el aumento en la hora, realizamos el cambio en el nombre del archivo utilizando sed:

prdapp03:/home/operator/test # for i in $(ls | head -6); do date1=$(echo "$i" | awk -F'[A-Z]' '{ print $1 }' | awk -F'2012' '{ print $2 }'); date2=$(echo $(echo "$i" | awk -F'[A-Z]' '{ print $1 }' | awk -F'2012' '{ print $2 }')+1 | bc); echo "$i : $date1 : $date2 : $(echo "$i" | sed s/$date1/$date2/)"; done
021215102012161427MEBC760830MDFNSR04.P7M.15EC4C : 161427 : 161428 : 021215102012161428MEBC760830MDFNSR04.P7M.15EC4C
028811102012133833GUMH600228HGTTDP02.P7M.11CC90 : 133833 : 133834 : 028811102012133834GUMH600228HGTTDP02.P7M.11CC90
033406112012104802HEZO860316HGTRVC06.P7M.131DC8 : 104802 : 104803 : 033406112012104803HEZO860316HGTRVC06.P7M.131DC8
037531102012151650CAJL850805HGTHMS07.P7M.1AA43C : 151650 : 151651 : 037531102012151651CAJL850805HGTHMS07.P7M.1AA43C
038315102012092333LUMN850419MQTNRN05.P7M.15A2C8 : 092333 : 092334 : 038315102012092334LUMN850419MQTNRN05.P7M.15A2C8
045913092012153205AEAF860124MGTRRR06.P7M.19FCB0 : 153205 : 153206 : 045913092012153206AEAF860124MGTRRR06.P7M.19FCB0
prdapp03:/home/operator/test #

Con el cambio validado en la prueba, realizamos el cambio de nombre, utilizando como entrada la lista proporcionada originalmente:

prdapp03:/home/operator/test # for i in $(cat lista_65K.txt); do date1=$(echo "$i" | awk -F'[A-Z]' '{ print $1 }' | awk -F'2012' '{ print $2 }'); date2=$(echo $(echo "$i" | awk -F'[A-Z]' '{ print $1 }' | awk -F'2012' '{ print $2 }')+1 | bc); mv $i $(echo "$i" | sed s/$date1/$date2/); done
prdapp03:/home/operator/test #

Con esto, se modificaron los archivos en unos 15 minutos 🙂 …

Al final solamente se trata de razonar el requerimiento y utilizar todos los recursos disponibles.

Adicionalmente, les comparto el link a dos sitios excelente que encontré, buscando como solucionar esta solicitud:

Espero les sirva…