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.
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:
- Better Bash Scripting in 15 Minutes – Robert Muth
- Navaja Suiza de Shell (Bash) – Aurelio Marinho Jargas
Espero les sirva…