Mis pruebas indicaron que sed
puede vincularse a la CPU con bastante facilidad en algo como esto. Si tiene una máquina multinúcleo, puede intentar generar múltiples sed
procesos con un script que se parece a esto:
#!/bin/sh
INFILE=data.txt
OUTFILE=fixed.txt
SEDSCRIPT=script.sed
SPLITLIMIT=`wc -l $INFILE | awk '{print $1 / 20}'`
split -d -l $SPLITLIMT $INFILE x_
for chunk in ls x_??
do
sed -f $SEDSCRIPT $chunk > $chunk.out &
done
wait
cat x_??.out >> output.txt
rm -f x_??
rm -f x_??.out
Intenta cambiar las dos primeras líneas a:
s/[ \t]*|[ \t]*/|/g
Lo mejor que pude hacer con sed fue este script:
s/[\s\t]*|[\s\t]*/|/g
s/[\s\t]*$//
s/^|/null|/
En mis pruebas, esto funcionó un 30% más rápido que su secuencia de comandos sed. El aumento en el rendimiento proviene de combinar las dos primeras expresiones regulares y omitir el indicador "g" donde no es necesario.
Sin embargo, un 30 % más rápido es solo una leve mejora (todavía debería tomar alrededor de una hora y media ejecutar el script anterior en su archivo de datos de 1 GB). Quería ver si podía hacerlo mejor.
Al final, ningún otro método que probé (awk, perl y otros enfoques con sed) funcionó mejor, excepto, por supuesto, una implementación simple de C. Como era de esperar con C, el código es un poco detallado para publicar aquí, pero si desea un programa que probablemente sea más rápido que cualquier otro método, puede echarle un vistazo.
En mis pruebas, la implementación de C finaliza en aproximadamente el 20 % del tiempo que tarda su secuencia de comandos sed. Por lo tanto, puede tardar unos 25 minutos en ejecutarse en su servidor Unix.
No dediqué mucho tiempo a optimizar la implementación de C. Sin duda, hay varios lugares donde el algoritmo podría mejorarse, pero, francamente, no sé si es posible reducir una cantidad significativa de tiempo más allá de lo que ya logra. En todo caso, creo que ciertamente pone un límite superior al tipo de rendimiento que puede esperar de otros métodos (sed, awk, perl, python, etc.).
Editar: La versión original tenía un error menor que posiblemente imprimiera algo incorrecto al final de la salida (por ejemplo, podría imprimir un "nulo" que no debería estar allí). Tuve algo de tiempo hoy para echarle un vistazo y lo arreglé. También optimicé una llamada a strlen()
eso le dio otro ligero impulso al rendimiento.