Textliste automatisch in Felder aufteilen (SED o.ä.)
- Ferdi
- Beiträge: 22
- Registriert: 27.10.2003 23:22:39
- Lizenz eigener Beiträge: MIT Lizenz
- Wohnort: Soest
Textliste automatisch in Felder aufteilen (SED o.ä.)
Ein Programm liefert als Export nur eine durch Leerzeichen getrennte
Textdatei (siehe Beispiel unten). Diese für Menschen lesbare Datei würde ich
gern durch automatisches Einfügen von Semikolon (Mehrzahl?) in eine für
Computern auswertbare Form bringen. Zu diesem Zweck habe ich bereits mit SED
experimentiert und durch den Befehl "ersetzen" die Leerzeichen vor einem
neuen Feld in ein Semikolon umwandeln können. Leider stehen zwischen den
Feldern mit fester Größe keine Leerzeichen sodaß ich mir mit diesem
Lösungsansatz die Daten des Feldes abschneide. Wie kann ich nun ein Zeichen
an beliebiger Stelle einfügen?
Ferdi
001Lieschen Mueller Musterweg 23 59555Menden
002Andreas Meier Testgasse 44 68798Dortmund
003Peter Schulz Kastanienallee 178964Regensburg
Textdatei (siehe Beispiel unten). Diese für Menschen lesbare Datei würde ich
gern durch automatisches Einfügen von Semikolon (Mehrzahl?) in eine für
Computern auswertbare Form bringen. Zu diesem Zweck habe ich bereits mit SED
experimentiert und durch den Befehl "ersetzen" die Leerzeichen vor einem
neuen Feld in ein Semikolon umwandeln können. Leider stehen zwischen den
Feldern mit fester Größe keine Leerzeichen sodaß ich mir mit diesem
Lösungsansatz die Daten des Feldes abschneide. Wie kann ich nun ein Zeichen
an beliebiger Stelle einfügen?
Ferdi
001Lieschen Mueller Musterweg 23 59555Menden
002Andreas Meier Testgasse 44 68798Dortmund
003Peter Schulz Kastanienallee 178964Regensburg
Hi Ferdi,
ich hab mal auf die schnelle ein Pythonscript erstellt, das Deine Datei umwandelt.
testlauf:
Ich denke, Du hast bei Deinem Beispiel ein Leerzeichen vergessen in der letzten Zeile, mein Script funktioniert auch wenn keine Hausnummer angegeben wurde, die Postleitzahl muss aber 5stellig sein!
Du kannst auch gleich eine Ausgabedatei angeben als 2. Parameter.
Gruß
Dookie
ich hab mal auf die schnelle ein Pythonscript erstellt, das Deine Datei umwandelt.
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
import sys
if len(sys.argv) > 1:
if sys.argv[1] == "-h":
print "usage: %s [infilename [outfilename]]" % (sys.argv[0],)
sys.exit(0)
infilename = sys.argv[1]
infile = open(infilename,"r")
else:
infile = sys.stdin
if len(sys.argv) > 2:
outfilename = sys.argv[2]
outfile = open(outfilename,"w")
else:
outfile = sys.stdout
for line in infile.readlines():
if line.strip() and line[0] != "#":
tmp = line.strip().split()
id = tmp[0][:3]
vorname = tmp[0][3:]
nachname = tmp[1]
strasse = tmp[2]
if len(tmp) > 4:
strasse += " "+tmp[3]
plz = tmp[4][:5]
ort = tmp[4][5:]
else:
plz = tmp[3][:5]
ort = tmp[3][5:]
outline = ";".join([id, vorname, nachname, strasse, plz, ort])
outfile.write(outline+"\n")
Code: Alles auswählen
fritz@seneca:~/Python/debianforum$ more testdat.txt
001Lieschen Mueller Musterweg 23 59555Menden
002Andreas Meier Testgasse 44 68798Dortmund
003Peter Schulz Kastanienallee 1 78964Regensburg
fritz@seneca:~/Python/debianforum$ converter.py testdat.txt
001;Lieschen;Mueller;Musterweg 23;59555;Menden
002;Andreas;Meier;Testgasse 44;68798;Dortmund
003;Peter;Schulz;Kastanienallee 1;78964;Regensburg
fritz@seneca:~/Python/debianforum$
Du kannst auch gleich eine Ausgabedatei angeben als 2. Parameter.
Gruß
Dookie
Das geht mit awk um einiges einfacher:Dookie hat geschrieben:Hi Ferdi,
ich hab mal auf die schnelle ein Pythonscript erstellt, das Deine Datei umwandelt.
...
Code: Alles auswählen
cat datei | awk '{ printf ("%s;%s;%s;%s %s;%s;%s\n", substr($1,1,3),substr($1,4),$2,$3,$4,substr($5,1,5), substr($5,6)) }'
als Script
Code: Alles auswählen
#!/bin/sh
cat $1 | awk '{ printf ("%s;%s;%s;%s %s;%s;%s\n", substr($1,1,3),substr($1,4),$2,$3,$4,substr($5,1,5), substr($5,6)) }'
[ jabber ] chimerer@amessage.de
Hi Chimerer,
nix für ungut, aber ich hätte es auch so coden können, was aber die lesbarkeit, die flexibilität und den Komfort beeinträchtigt hätte.
Bei meinem Script kannst Du auch darauf verzichten Ein und Ausgabedatei anzugeben, dann wird einfach stdin bzw. stdout verwendet, so kann auch, ohne Änderung es Scripts die Ausgabe von einem anderen Script als Eingabe verwendet werden und die Ausgabe wieder an ein anderes Programm weigergeleitet werden.
Man könnte die Zeilen auch mit einer Regex zerlegen. Aber hauptsache es läuft.
Gruß
Dookie
nix für ungut, aber ich hätte es auch so coden können, was aber die lesbarkeit, die flexibilität und den Komfort beeinträchtigt hätte.
Bei meinem Script kannst Du auch darauf verzichten Ein und Ausgabedatei anzugeben, dann wird einfach stdin bzw. stdout verwendet, so kann auch, ohne Änderung es Scripts die Ausgabe von einem anderen Script als Eingabe verwendet werden und die Ausgabe wieder an ein anderes Programm weigergeleitet werden.
Man könnte die Zeilen auch mit einer Regex zerlegen. Aber hauptsache es läuft.
Gruß
Dookie
Hi Dookie,
Funktioniert bei der awk-Variante auch ohne weiteres.Dookie hat geschrieben:Hi Chimerer,
Bei meinem Script kannst Du auch darauf verzichten Ein und Ausgabedatei anzugeben, dann wird einfach stdin bzw. stdout verwendet, so kann auch, ohne Änderung es Scripts die Ausgabe von einem anderen Script als Eingabe verwendet werden und die Ausgabe wieder an ein anderes Programm weigergeleitet werden.
Gruß
Dookie
Jep. Aber meine Variante ist trotzdem doppelt so schnell.Man könnte die Zeilen auch mit einer Regex zerlegen. Aber hauptsache es läuft.
Code: Alles auswählen
chimerer@horizon:~$ time cat cc | ./python.py
001;Lieschen;Mueller;Musterweg 23;59555;Menden
002;Andreas;Meier;Testgasse 44;68798;Dortmund
003;Peter;Schulz;Kastanienallee 1;78964;Regensburg
real 0m0.023s
user 0m0.020s
sys 0m0.010s
Code: Alles auswählen
chimerer@horizon:~$time cat cc | ./awk.sh
001;Lieschen;Mueller;Musterweg 23;59555;Menden
002;Andreas;Meier;Testgasse 44;68798;Dortmund
003;Peter;Schulz;Kastanienallee 1;78964;Regensburg
real 0m0.009s
user 0m0.000s
sys 0m0.010s
[ jabber ] chimerer@amessage.de
- godsmacker
- Beiträge: 902
- Registriert: 16.03.2003 21:50:26
- Lizenz eigener Beiträge: Artistic Lizenz
- Wohnort: Chemnitz
-
Kontaktdaten:
Kann ich locker mit der Perl Zeile unterbieten:
Code: Alles auswählen
while(<>) { print join(';', ($_ =~ /^(\d{3})(\w+) (\w+) (.*?) (\d+)(\w+)$/)),"\n"; }
Code: Alles auswählen
real 0m0.005s
user 0m0.000s
sys 0m0.000s
Ist jemand noch schneller?godsmacker hat geschrieben:Kann ich locker mit der Perl Zeileunterbieten:Code: Alles auswählen
while(<>) { print join(';', ($_ =~ /^(\d{3})(\w+) (\w+) (.*?) (\d+)(\w+)$/)),"\n"; }
Code: Alles auswählen
real 0m0.005s user 0m0.000s sys 0m0.000s
[ jabber ] chimerer@amessage.de
- suntsu
- Beiträge: 2947
- Registriert: 03.05.2002 10:45:12
- Lizenz eigener Beiträge: MIT Lizenz
- Wohnort: schweiz
-
Kontaktdaten:
Also ich würde Java/StringTokenizer nehmen
Wäre aba wohl ned so schnell.
edit:
Mir ist leider noch nicht ganz klar mit was ihr da die Zeit messt
gruss
manuel
Wäre aba wohl ned so schnell.
edit:
Code: Alles auswählen
import java.util.*;
public class STTest {
public static void main(String[] args) {
String s1 = "001Lieschen Mueller Musterweg 23 59555Menden";
s1 = s1 + "002Andreas Meier Testgasse 44 68798Dortmund";
s1 = s1 + "003Peter Schulz Kastanienallee 178964Regensburg";
StringTokenizer tokenizer = new StringTokenizer( s1 );
while ( tokenizer.hasMoreTokens() )
System.out.println( tokenizer.nextToken() );
}
}
gruss
manuel
- suntsu
- Beiträge: 2947
- Registriert: 03.05.2002 10:45:12
- Lizenz eigener Beiträge: MIT Lizenz
- Wohnort: schweiz
-
Kontaktdaten:
doh...
Ist ja wie in der Schule >> Ich lese die Aufgaben nie durch
Wäre wohl passender.
Ist ja wie in der Schule >> Ich lese die Aufgaben nie durch
Code: Alles auswählen
public class STTest {
public static void main(String[] args) {
String s1 = "001Lieschen Mueller Musterweg 23 59555Menden";
s1 = s1 + "002Andreas Meier Testgasse 44 68798Dortmund";
s1 = s1 + "003Peter Schulz Kastanienallee 178964Regensburg";
s1 = s1.replace(' ',';');
System.out.println(s1);
}
}
- Ferdi
- Beiträge: 22
- Registriert: 27.10.2003 23:22:39
- Lizenz eigener Beiträge: MIT Lizenz
- Wohnort: Soest
Sieht alles echt toll aus aber...
Vielen Dank für die vielen Lösungsmöglichkeiten. Das gibt mir mal wieder das
gute Gefühl, mit Linux das richtige System in der Hand zu haben.
Verschiedene Wege führen zu demselben Ziel - man kann sich frei entscheiden,
ob man es lieber kurz und knackig oder ordentlich strukturiert haben möchte.
AWK kenne ich schon ein wenig und habe durch Chimerers Beispiel weitere Tips
bekommen. Mit Python wollte ich mich immer schon einmal beschäftigen und
Dookies Lösungsvorschlag ist nen guter Einstieg dafür. Leider ist mein Problem
noch nicht ganz gelöst.
Zum einen ist die betreffende Datei leider bei weitem komplexer als mein
Beispiel es deutlich gemacht hat (104 Felder pro Zeile / Datensatz). Dadurch
würde bei der Python-Lösung ein enormer Programmieraufwand entstehen.
Zum anderen fehlen in einigen Datensätzen das eine oder andere Feld (wie es
Dookie bereits angedeutet hat), wodurch das AWK-Script in Schwierigkeiten
kommt da Leerzeichen ja als Trenner gelten und das leere Feld ja nicht als
Feld gewertet wird.
Ich füge deshalb nocheinmal ein Beispiel an - diesmal mit Unterstrichen als
Leerzeichen da diese mir in meinem ersten Beispiel weggekürzt wurden:
001Lieschen_______Mueller______________Auf_dem_Damm 12_________59555Menden
002Andreas________Meier________________Testgasse_44____________68798Dortmund
003Peter__________Schulz_______________________________________78964Regensburg
004Sidam_Al_______Sechmet______________Kastanienallee_23____________Berlin
Ein Mensch sieht die Struktur der Liste (bei nicht proportionaler Schrift)auf
den ersten Blick und könnte durch daß "stumpfe" Einfügen von z.B. einem
Tabulator am Beginn eines jeden Feldes die Liste in Felder aufteilen. Das
anschließende Herausfiltern der überschüssigen Leerzeichen pro Feld ist dann nur
noch ein Klacks und würde die Anzahl der Felder pro Datensatz nicht verändern.
gute Gefühl, mit Linux das richtige System in der Hand zu haben.
Verschiedene Wege führen zu demselben Ziel - man kann sich frei entscheiden,
ob man es lieber kurz und knackig oder ordentlich strukturiert haben möchte.
AWK kenne ich schon ein wenig und habe durch Chimerers Beispiel weitere Tips
bekommen. Mit Python wollte ich mich immer schon einmal beschäftigen und
Dookies Lösungsvorschlag ist nen guter Einstieg dafür. Leider ist mein Problem
noch nicht ganz gelöst.
Zum einen ist die betreffende Datei leider bei weitem komplexer als mein
Beispiel es deutlich gemacht hat (104 Felder pro Zeile / Datensatz). Dadurch
würde bei der Python-Lösung ein enormer Programmieraufwand entstehen.
Zum anderen fehlen in einigen Datensätzen das eine oder andere Feld (wie es
Dookie bereits angedeutet hat), wodurch das AWK-Script in Schwierigkeiten
kommt da Leerzeichen ja als Trenner gelten und das leere Feld ja nicht als
Feld gewertet wird.
Ich füge deshalb nocheinmal ein Beispiel an - diesmal mit Unterstrichen als
Leerzeichen da diese mir in meinem ersten Beispiel weggekürzt wurden:
001Lieschen_______Mueller______________Auf_dem_Damm 12_________59555Menden
002Andreas________Meier________________Testgasse_44____________68798Dortmund
003Peter__________Schulz_______________________________________78964Regensburg
004Sidam_Al_______Sechmet______________Kastanienallee_23____________Berlin
Ein Mensch sieht die Struktur der Liste (bei nicht proportionaler Schrift)auf
den ersten Blick und könnte durch daß "stumpfe" Einfügen von z.B. einem
Tabulator am Beginn eines jeden Feldes die Liste in Felder aufteilen. Das
anschließende Herausfiltern der überschüssigen Leerzeichen pro Feld ist dann nur
noch ein Klacks und würde die Anzahl der Felder pro Datensatz nicht verändern.
- suntsu
- Beiträge: 2947
- Registriert: 03.05.2002 10:45:12
- Lizenz eigener Beiträge: MIT Lizenz
- Wohnort: schweiz
-
Kontaktdaten:
Immo muss man das ziemlich hart ausprogrammieren, und ist warscheinlich trotzdem nicht vor Fehlern sicher.
Wer auf der Welt exportiert ein solches Format?
gruss
manuel
edit: oder ist das Tab-Delemited?
Wer auf der Welt exportiert ein solches Format?
gruss
manuel
edit: oder ist das Tab-Delemited?
Zuletzt geändert von suntsu am 28.10.2003 22:33:51, insgesamt 1-mal geändert.
- godsmacker
- Beiträge: 902
- Registriert: 16.03.2003 21:50:26
- Lizenz eigener Beiträge: Artistic Lizenz
- Wohnort: Chemnitz
-
Kontaktdaten:
- Ferdi
- Beiträge: 22
- Registriert: 27.10.2003 23:22:39
- Lizenz eigener Beiträge: MIT Lizenz
- Wohnort: Soest
Trennung klappt mit ein wenig AWKerei
Vielen Dank an alle. Habe mir aus den geposteten Antworten ein (etwas kompliziertes) Script zurechtgebastelt, welches meinen Anforderungen genügt.
Ferdi
Ferdi