En una gran aseduradora nos volcaban ficheros inmensos de datos de
operaciones sobre polizas desde el host,
ficheros con millones de registros.
Eran ficheros planos y ellos mismos elegían el carácter separador de
campos.
Esos ficheros los subíamos, a su vez, a otra base de datos que
los cargaba utilizando, para interpretar la separación de campos,
el carácter indicado en cada caso.
Esta carga se realizaba empleando el programa de carga suministrado
junto con el sistema de gestión de la base de datos.
El proceso de carga era lento y, además,
con frecuencia, el carácter que habían elegido,
aparecía en algún campo de texto de algún registro.
Por ejemplo, elegían el asterisco y
algunos campos de observaciones contenían asteriscos.
Al llegar al primer registro con más separadores de los esperados
el proceso de carga abortaba tras horas de ejecución.
La solución era programar un comprobador de ficheros,
muy rápido, que antes de iniciar el proceso de carga,
comprobara que todas las líneas del fichero contuvieran el mismo
números de caracteres separadores de campo,
asumiendo como correcto el número de separadores de la primera línea del fichero.
Y sólo comenzar la carga a la base de datos tras comprobar que
el fichero era correcto.
Hacía ya mucho tiempo que no programaba en C y
esta era una ocasión para volver a él.
El programa se llama chksep.exe,
esta hecho en lenguaje C en pocas horas,
por lo que seguro que se puede mejorar.
Se ejecuta como
chksep 42 < fichero.txt
,
donde el 42 es el código ASCII del caracter *,
que era el separador de campos habitual,
aunque se puede elegir cualquier otro carácter,
por ejemplo,
chksep 59 < fichero.txt
,
para el punto y coma.
El programa visualiza las líneas donde
el número de separadores de campo es diferente al de la primera línea.
En un computador portatil normal este programa es capaz de revisar
un Giga en 2 minutos 15 segundos,
lo que equivalía con los ficheros reales que nos daban a
unos 800.000 registros por minuto.
Por lo que en 5 ó 10 minutos se podía evitar que luego abortara una carga de horas.
El programa también cuenta el número de líneas del fichero.
A continuación pongo el ciclo principal del programa y
en el fichero PDF adjunto a este post el código fuente completo.
Me gustan mucho los programas eficaces de pocas líneas de código y
que sean eficientes ya lo considero un regalo.
while((chrInp=getc(stdin)) != EOF)
{
if(chrInp==sepChr) { sepCnt++; } /* Es un separador */
else if(chrInp==EOL) /* Es un salto de linea */
{
if(linCnt==1) /* Estabamos en la 1ª linea */
{
sepFst = sepCnt; /* Referencia para el resto de lineas */
printf("\n[%d] [%s] en la primera linea.", sepFst, sepStr);
}
else /* Linea normal */
{
if(sepFst!=sepCnt) /* Faltan o sobran separadores */
{
printf("\nlinea %d: [%d] [%s] en vez de [%d].",
linCnt, sepCnt, sepStr, sepFst);
}
}
linCnt++; /* Incrementar el contador de lineas */
sepCnt = 0; /* Poner a cero el contador de separadores */
}
}
printf("\nProcesadas [%d] lineas.", linCnt);