Mes tests ont indiqué que sed
peut devenir lié au processeur assez facilement sur quelque chose comme ça. Si vous avez une machine multicœur, vous pouvez essayer de générer plusieurs sed
processus avec un script qui ressemble à ceci :
#!/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
Essayez de remplacer les deux premières lignes par :
s/[ \t]*|[ \t]*/|/g
Le mieux que j'ai pu faire avec sed, c'est ce script :
s/[\s\t]*|[\s\t]*/|/g
s/[\s\t]*$//
s/^|/null|/
Dans mes tests, cela a fonctionné environ 30% plus rapidement que votre script sed. L'augmentation des performances provient de la combinaison des deux premiers regexen et de l'omission du drapeau "g" là où il n'est pas nécessaire.
Cependant, 30% plus rapide n'est qu'une légère amélioration (cela devrait encore prendre environ une heure et demie pour exécuter le script ci-dessus sur votre fichier de données de 1 Go). Je voulais voir si je pouvais faire mieux.
En fin de compte, aucune autre méthode que j'ai essayée (awk, perl et d'autres approches avec sed) ne s'est mieux comportée, à l'exception - bien sûr - d'une simple implémentation en C. Comme on pouvait s'y attendre avec C, le code est un peu verbeux pour être publié ici, mais si vous voulez un programme qui sera probablement plus rapide que n'importe quelle autre méthode, vous voudrez peut-être y jeter un coup d'œil.
Dans mes tests, l'implémentation C se termine en environ 20% du temps nécessaire pour votre script sed. L'exécution sur votre serveur Unix peut donc prendre environ 25 minutes.
Je n'ai pas passé beaucoup de temps à optimiser l'implémentation du C. Il y a sans aucun doute un certain nombre d'endroits où l'algorithme pourrait être amélioré, mais franchement, je ne sais pas s'il est possible de gagner beaucoup de temps au-delà de ce qu'il réalise déjà. Au contraire, je pense que cela place certainement une limite supérieure au type de performances que vous pouvez attendre des autres méthodes (sed, awk, perl, python, etc.).
Modifier : La version originale avait un bogue mineur qui l'amenait à imprimer la mauvaise chose à la fin de la sortie (par exemple, pouvait imprimer un "null" qui ne devrait pas être là). J'ai eu le temps aujourd'hui d'y jeter un coup d'œil et de le réparer. J'ai également optimisé un appel au strlen()
cela lui a donné une autre légère amélioration des performances.