Folgendes Problem: Ich möchte eine csv-Datei in z.B. OpenOffice importieren, um Spaltensummen zu berechnen. Leider verwendet die csv-Datei den Punkt statt dem Beistrich als Kommazeichen und hintendran steht auch noch das Prozentzeichen. Globales Ersetzen des Punktes ist keine Lösung, weil ja auch in anderen (Text-) Spalten Punkte vorkommen.( Die "Mb" Spalte ist egal.) Da greife ich zu
sed.
Eine Beispielzeile des Textes:
389 0.79% 1.25 Mb 0.21% /gimp1.2/zuschneiden.html
Das passende sed-Kommando lautet so:
sed 's/\([0-9]\{1,3\}\)\.\([0-9]\{2\}\)%/\1,\2/g'
Horror, nicht? Ich werde das jetzt ein bisschen aufdröseln.
Die Basis für das Ganze ist sed's "substitute", also
s (=ersetzen).
sed 's/das/jenes/g'
Das bedeutet, sed ersetzt "das" durch "jenes", und zwar global (g) im gesamten Dokument.
Bei meinem Problem geht es nur um Punkte, die von Zahlen eingeschlossen sind. Vorne sind es nie mehr als drei Stellen, es ist aber mindestens eine.
[0-9]\{1,3\}
Dieser Ausdruck steht für eine ein- bis dreistellige Zahl. Zu beachten, die geschwungenen Klammern müssen mit Backslash escaped werden.
Nun will ich aber nur den Punkt ersetzen, die Zahlen aber selbstverständlich mitnehmen. Sed kennt dazu Platzhalter (\1, \2 usw.), die sich auf einen Ausdruck in Runden Klammern beziehen.
Die Regex (Regular Expresssion)
...\([0-9]\{1,3\}\)...
...kann also, da es der erste Ausdruck in runden Klammern ist, als
\1 mitgenommen werden. Der nächste Ausdruck in runden Klammern wäre \2, usw. Auch die runden Klammern müssen durch Backslash escaped werden. Genau so übrigens der Punkt, damit auch wirklich der wörtliche Punkt und nicht "ein beliebiges Zeichen" gemeint ist.
In der csv-Datei haben alle Zahlen zwei Nachkommastellen. Die passende Regex schaut so aus:
\([0-9]\{2\}\)
Ein weiteres Merkmal ist das Prozentzeichen hintendran, das ich bei der Gelegenheit auch gleich loswerden möchte. Ich nehme es zum Suchbegriff dazu, allerdings
außerhalb der runden Klammern, damit es nicht mitgenommen wird.
s/ \([0-9]\{1,3\}\) \. \([0-9]\{2\}\) % / \1,\2 /g
Punkt Prozent
Regex 1 Regex 2 Referenz 1
Referenz 2
Beistrich
Zusammenfassung:
Regex 1 = 1 bis 3-stellige Zahl
\. = ein (wörtlicher) Punkt
Regex 2 = 2-stellige Zahl (Nachkommastellen)
% = ein Prozentzeichen (wird wegfallen)
\1 = Referenz auf die erste Regex
, = der Beistrich (ersetzt den Punkt)
\2 = Referenz auf die zweite Regex
Sinnvollerweise wird das sed-Kommando in einer Pipe verwendet, z.B.
cat allurls.csv | sed 's/\([0-9]\{1,3\}\)\.\([0-9]\{2\}\)%/\1,\2/g' > neuedatei.csv
Das ersetzt die unerwünschten Punkte durch Beistrich, entfernt die Prozentzeichen und speichert das Ergebnis in einer neuen Datei.
Das Ergebnis (vgl. Beispielzeile oben)
:
389 0,79 1.25 Mb 0,21 /gimp1.2/zuschneiden.html