staging.inyokaproject.org

Zahl in csv Datei 1000er Trennzeichen hinzufügen

Status: Gelöst | Ubuntu-Version: Server 20.10 (Groovy Gorilla)
Antworten |

Loki969

Anmeldungsdatum:
15. März 2008

Beiträge: 580

Hallo,

ich hab auf einem Raspberry Server einige Dateien liegen im csv Format. darin befinden sich Messwerte in Zahlenform. sind 4-5stellige Zahlen, leider ohne Tausendertrennzeichen. gibt es eine einfache Möglichkeit die Zahlen in der Datei z.B

1
12345  oder  1234

in

1
12.345  bzw.  1.234

umzuwandeln?

Danke

seahawk1986

Anmeldungsdatum:
27. Oktober 2006

Beiträge: 10978

Abgesehen davon, dass das totaler Mist ist, wenn man die Daten jemals programmatisch weiterverarbeiten will (ich würde nach Möglichkeit immer Rohdaten von der Ausgabe trennen) unter der Annahme, dass das Trennzeichen ein Komma (,) ist:

$ sed -E 's/([0-9])([0-9]{3}),/\1.\2,/g;s/([0-9])([0-9]{3})$/\1.\2/g' << EOF
12345,123,1234
EOF
12.345,123,1.234 

Loki969

(Themenstarter)

Anmeldungsdatum:
15. März 2008

Beiträge: 580

Hallo,

danke für den Tip, werd mal schauen ob ich nicht doch die Rohdaten so weiterverwenden kann, wird evtl. sinnvoller und einfacher sein. Aber als zwischenlösung ist das schon mal ok.

Danke für die schnelle Hilfe!

Udalrich

Avatar von Udalrich

Anmeldungsdatum:
15. Mai 2019

Beiträge: 472

Gut lesbar ist es in AWK. Die Formatierung des printf-Befehls ist wie in Posix-C üblich, also sorgt das Apostroph bei %'d für ein Tausender-Trennzeichen bei der printf-Ausgabe. Die Eingabedatei.txt enthalte pro Zeile eine Zahl ohne Tausendertrennung:

Im Terminal als AWK-Einzeiler aufgerufen, müssen wir das printf-Apostroph als ESC-Sequenz \47 schreiben:

gawk '{ printf "%\47d \n", $0 }' Eingabedatei.txt


Oder das Ergebnis statt auf dem Bildschirm ausgeben in Datei umleiten:

gawk '{ printf "%\47d \n", $0 }' Eingabedatei.txt > Ausgabedatei.txt


Beim Benutzen einer AWK-Skriptdatei entfiele die ESC-Sequenz. Datei tausender.awk anlegen mit der Zeile:

{ printf "%'d \n", $0 }

Und dann im Terminal aufrufen:

gawk --file tausender.awk Eingabedatei.txt > Ausgabedatei.txt


P.S. Leerstelle vor dem Neuzeilenzeichen \n ist jeweils unnötig, macht das Ganze jedoch lesbarer.

seahawk1986

Anmeldungsdatum:
27. Oktober 2006

Beiträge: 10978

In den coreutils gibt es auch noch numfmt, damit geht das entspannter als mit sed oder awk (achtung, das berücksichtigt die LOCALE-Settings, weshalb ein Komma als Trennzeichen in der csv-Datei mit englischen Lokales problematisch ist):

$ LANG=de_DE.UTF-8 numfmt --field 1- --grouping -d ',' << EOF
12345,123,1234
EOF
12.345,123,1.234 

Udalrich

Avatar von Udalrich

Anmeldungsdatum:
15. Mai 2019

Beiträge: 472

seahawk1986 schrieb:

In den coreutils gibt es auch noch numfmt, damit geht das entspannter als mit sed oder awk

Spitze, und wieder etwas hinzugelernt! ☺

Dieses Coreutils ist ja eine regelrechte Schatztruhe.

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 12527

Udalrich schrieb:

Gut lesbar ist es in AWK. Die Formatierung des printf-Befehls ist wie in Posix-C üblich, also sorgt das Apostroph bei %'d für ein Tausender-Trennzeichen bei der printf-Ausgabe. Die Eingabedatei.txt enthalte pro Zeile eine Zahl ohne Tausendertrennung:

Man achte aber darauf, dass die Sprachinformationen aus der Umgebung benutzt werden:

1
2
3
4
5
6
$ awk 'BEGIN {printf "%'\''d\n", 1234567}'
1.234.567
$ echo "$LC_NUMERIC"
de_DE.UTF-8
$ LC_NUMERIC=en_US.UTF-8 awk 'BEGIN {printf "%'\''d\n", 1234567}'
1,234,567

Im Terminal als AWK-Einzeiler aufgerufen, müssen wir das printf-Apostroph als ESC-Sequenz \47 schreiben:

gawk '{ printf "%\47d \n", $0 }' Eingabedatei.txt

Interessant. Es geht aber auch anders:

1
gawk '{ printf "%'\''d \n", $0 }' Eingabedatei.txt

Zur Erläuterung, der aufgerufene Prozess (hier gawk) sieht das so:

1
2
$ echo 'BEGIN {printf "%'\''d\n", 1234567}'
BEGIN {printf "%'d\n", 1234567}

Arg, mein args.sh Skript baut da Mist:

1
2
3
4
5
$ args.sh awk 'BEGIN {printf "%'\''d\n", 1234567}'
arg count: 2
arg[1]: 'awk'
arg[2]: 'BEGIN {printf "%'d
", 1234567}'

Da muss ich wohl noch mal ran.

P.S. Leerstelle vor dem Neuzeilenzeichen \n ist jeweils unnötig, macht das Ganze jedoch lesbarer.

Leerzeichen am Zeilenende sind des Teufels: man sieht sie nicht, aber manche Verarbeitung kann das aus der Bahn werfen. Außerdem ist das eine ungeheure Verschwendung von Zeichen - Leerzeichen müssen ja sowieso schon ständig als Lückenbüßer herhalten. 😉

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 12527

rklm schrieb:

Arg, mein args.sh Skript baut da Mist:

1
2
3
4
5
$ args.sh awk 'BEGIN {printf "%'\''d\n", 1234567}'
arg count: 2
arg[1]: 'awk'
arg[2]: 'BEGIN {printf "%'d
", 1234567}'

Jetzt nicht mehr:

1
2
3
arg count: 2
arg[1]: 'awk'
arg[2]: 'BEGIN {printf "%'d\n", 1234567}'

Das geänderte Skript steht auf meiner Profilseite.

Antworten |