Meine Tests haben ergeben, dass sed
kann bei so etwas ziemlich leicht CPU-gebunden werden. Wenn Sie einen Computer mit mehreren Kernen haben, können Sie versuchen, mehrere sed
zu spawnen Prozesse mit einem Skript, das in etwa so aussieht:
#!/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
Versuchen Sie, die ersten beiden Zeilen zu ändern:
s/[ \t]*|[ \t]*/|/g
Das Beste, was ich mit sed machen konnte, war dieses Skript:
s/[\s\t]*|[\s\t]*/|/g
s/[\s\t]*$//
s/^|/null|/
In meinen Tests lief dies etwa 30 % schneller als Ihr sed-Skript. Die Leistungssteigerung ergibt sich aus der Kombination der ersten beiden regulären Ausdrücke und dem Weglassen des "g"-Flags, wo es nicht benötigt wird.
30 % schneller ist jedoch nur eine leichte Verbesserung (es sollte immer noch etwa anderthalb Stunden dauern, um das obige Skript auf Ihrer 1-GB-Datendatei auszuführen). Ich wollte sehen, ob ich es besser machen könnte.
Am Ende schnitt keine andere Methode, die ich ausprobiert habe (awk, perl und andere Ansätze mit sed), besser ab, außer natürlich einer einfachen alten C-Implementierung. Wie bei C zu erwarten, ist der Code etwas ausführlich, um ihn hier zu posten, aber wenn Sie ein Programm suchen, das wahrscheinlich schneller ist als jede andere Methode da draußen, sollten Sie es sich vielleicht einmal ansehen.
In meinen Tests ist die C-Implementierung in etwa 20 % der Zeit abgeschlossen, die für Ihr Sed-Skript benötigt wird. Es kann also ungefähr 25 Minuten dauern, bis es auf Ihrem Unix-Server läuft.
Ich habe nicht viel Zeit damit verbracht, die C-Implementierung zu optimieren. Zweifellos gibt es eine Reihe von Stellen, an denen der Algorithmus verbessert werden könnte, aber ehrlich gesagt weiß ich nicht, ob es möglich ist, über das hinaus, was er bereits erreicht, erheblich Zeit zu sparen. Wenn überhaupt, denke ich, dass es sicherlich eine Obergrenze dafür setzt, welche Art von Leistung Sie von anderen Methoden (sed, awk, perl, python usw.) erwarten können.
Bearbeiten: Die Originalversion hatte einen kleinen Fehler, der dazu führte, dass am Ende der Ausgabe möglicherweise das Falsche gedruckt wurde (z. B. konnte eine "Null" gedruckt werden, die nicht dort sein sollte). Ich hatte heute etwas Zeit, um es mir anzusehen und das zu beheben. Ich habe auch einen Aufruf von strlen()
wegoptimiert das gab ihm einen weiteren leichten Leistungsschub.