Weller
Anmeldungsdatum: 10. Januar 2007
Beiträge: 104
Wohnort: Gebhardshain
|
Hallo! Ich habe eine Textdatei bekommen mit wild zusammengewürfelten Adressen. Leider kein CR nach jeder Adresse und kein vernünftiges Trennzeichen zwischen den einzelnen Daten. Gibt es eine Möglichkeit das in ordentliches CSV umzuwandeln zur Weiterverarbeitung? Hier ein Datenbeispiel: KdNr., Zusatz, Vorname Name Straße; PLZ Ort KdNr., Zusatz, Vorname Name Straße; PLZ Ort KdNr., Zusatz, Vorname Name Straße; PLZ Ort KdNr., Zusatz, Vorname Name Straße; PLZ Ort KdNr., Zusatz, Vorname Name Straße; PLZ Ort KdNr., Zusatz, Vorname Name Straße; PLZ Ort KdNr., Zusatz, Vorname Name Straße; PLZ Ort KdNr., Zusatz, Vorname Name Straße; PLZ Ort So steht der Kram einfach hintereinander ☹ Problem: man kann nichtmal das ASCII Zeichen 32 als Trenner zwischen Ort und KdNr. nehmen, weil es ja auch Orte bestehende aus mehreren Worten gibt... Hat jmd. eine Idee? Gruß, Andreas Welelr
|
xoanon
Anmeldungsdatum: 12. Dezember 2006
Beiträge: 121
Wohnort: Hamburg
|
naja \^^ plz ist ne zahl ... kdnr auch ? RegExp und Perl sind dein freund! s/(\d\d\d\d\d)\s(.*?)\s(\d+)/$1\s$2\n$3/g # ok nun sind zeilen umbrüche drinne: KdNr., Zusatz, Vorname Name Straße; PLZ Ort KdNr., Zusatz, Vorname Name Straße; PLZ Ort KdNr., Zusatz, Vorname Name Straße; PLZ Ort KdNr., Zusatz, Vorname Name Straße; PLZ Ort Öde wird "Vorname Name Straße". Zum einen könntest du dir eine Datei erstellen mit allen zeilen bei denen "Vorname Name Straße" nicht auf /(.*?)\s(.*?)\s(.*?)\s(\d+[a-z]?)/ passt: "Maria Bärbel Mustermann Vogelstrasse 12a". Und die halt per Hand nacharbeiten. Gemein sind die Strassen. "Stiller Winkel", "Zum Brunnen" etc ... ohne Strassen Verzeichnisse wüste ich nicht wie man das sicher aufdröseln kann. z.B. "Bärbel Mustermann Waldweg 1" → String, space, String, space, string, space , zahl + u.u. ein buchstabe → /(.*?)\s(.*?)\s(.*?)\s(\d+[a-z]?)/
|
u.li
Anmeldungsdatum: 12. Mai 2007
Beiträge: 503
Wohnort: Hürth
|
Das sollte funktionieren, solange alle Personen nur jeweils einen Vor- und Nachnamen haben:
#!/usr/bin/env perl -w
use strict;
use warnings;
while ( <> ) {
# in einzelne Einträge teilen
while ( s/(\d+),(.+?)(\d+,|$)/$3/ ) {
my $kdnr = $1;
#den Eintrag zerschnippeln
print "$kdnr:$1:$2:$3:$4:$5:$6\n" if( $2 =~ /\s?(.*?),\s(.+?)\s(.+?)\s(.+?);\s?(\d+)\s(.+)/ );
}
} (speichern und aufrufen mit ./skript.pl datei)
Wenn mehrere Vornamen abgespeichert sind, gibt es wie xoanon schon gesagt hat, keine Möglichkeit (die ich sehe), das automatisch auseinanderzufummeln.
|
xoanon
Anmeldungsdatum: 12. Dezember 2006
Beiträge: 121
Wohnort: Hamburg
|
bei den Nachnamen muss man auf jeden fall mit \s rechnen: "el Moncef", "van Braun", "von Gummersbach" "de Sade" usw ...
|
Weller
(Themenstarter)
Anmeldungsdatum: 10. Januar 2007
Beiträge: 104
Wohnort: Gebhardshain
|
Hallo! Irgendwie wird ein Großteil übergangen. Aus meinen ursprünglich etwa 4 MB Daten wurden nach durchlauf des geposteten Scripts etwa 20 kB... Gruß, Andreas
|
user_unknown
Anmeldungsdatum: 10. August 2005
Beiträge: 17622
Wohnort: Berlin
|
Wenn Du ein wenig anonymisierte Sampledaten schickst wird es wahrscheinlich noch besser. Mit
head urdata | sed 's/[b-zB-Z]/a/g' > anon.sample sollte das leicht möglich sein. Die 10 Zeilen manuell umbrechen, damit man die Gemeinsamkeiten besser sieht.
|
Weller
(Themenstarter)
Anmeldungsdatum: 10. Januar 2007
Beiträge: 104
Wohnort: Gebhardshain
|
aA0A, A, aaaa. aa. aaaa aaaaaaa aaaaaaa. 27; 49536 aaaaaa aA0Aa, A, aaaaaa aaaaaaa aaaaaaaaaaaa 2 a; 37085 aöaaaaaaa aA0Aaa, A, aa. aaaaaaa aaaaaaaaaa aaaaaaaaaa. 12; 66117 aaaaaaüaaaa aaaaaaaaaaaaaa; 66117 aaaaaaüaaaa aA0aAa, A, aaaaaaaaa aaaaa aA0aa, A, aaaaa aaaaaa aaaaaaaaa aaaaaaa 422; 44805 aaaaaa aA0aaa, A, Aaaaaaaaa aaaaa aaaaaaaa. 34; 96215 aaaaaaaaaaa aA0aA, A, aaaaa aaaaaa aaaaaaa 196; 48599 aaaaaa aaaaaaaaa. 28; 48599 aaaaaa aA0aa, A, aaa aaaaaaa aaaaaaaaaaaa 35; 03055 aaaaaaa aA0aaa, A, aaaaaaa aaaaa aaaaaaaa. 44; 45881 aaaaaaaaaaaaa aaaaaaaaaaaaa. 11; 48159 aüaaaaa aA0aa, A, aaaaaaa aaaaa aaaaaaaaaaaaa 9; 95652 aaaaaaaaaa aA0aaa, A, aaaaaaaa aaaaaa aA0aa, A, aüaaaaa aaaaa aaaaaaaaaa. 54; 01129 aaaaaaa aA0aaa, A, aa. aaaaaa aaaaa aaaaaaaaaa aaa. 14; 99086 aaaaaa aA0aaa, A, aaaaa aaaaaa aaaaaa aaa 1; 74653 aüaaaaaaa aA0a, A, aaaaaa aaaaaaaa aA0aa, A, aaaaa aaa aaaaaaaaa-aaaaa-aaa. 18; 36043 aaaaa aA0aaa, A, aaaaaaaa aaaaaaaaa aaaaaaaaaaaaaaa. 87; 98708 aaaaaa aA0aaa, A, aaaaaa aaaaaaa aaaaaaaa. 6; 90542 aaaaaaaa aA0aa, A, aaaaa aaaaaa aaaaaaaaaa aaa. 38; 15234 aaaaaaaaa / aaaa aaaaaaaaaaa. 7; 15236 aaaaaaaaa / aaaa aA0aa, A, aaaa.aa.aaa. aaa aaaa aaaaaaaaaaaa 7 a; 85567 aaaaaaa aA0aaa, A, aaaaaaaa aaaaaa aaaaa-aaaaa-aaa. 35; 50827 aöaa aA0aaa, A, aaaaaa aaaaaa-aaaaaaa aaüaa aaaaa 19; 15754 aaaaaaaa / aa aaaaaa aA0aaa, A, aaaaa aaaaaaaaaaa aaa aaaa 688; 27498 aaaaaaaaa aA0aa, A, aa. aaaaaa aaaaa aaaaaaaaaa aaa. 14; 99086 aaaaaa aA0aaa, A, aaaa. aa. aaaa aaaaaaa aA0a, A, aa. aaaaa aaaaaaaaaa aaa aaa aaaaaaaa 11; 49808 aaaaaa aA0aaa, A, aaaa aüaaa aaaaaaaaa 13; 66802 Üaaaaaaaa aaa. a. aaaaaaaaa- aaaaaa 1; 66287 aaaaaaaaaaa aA0aaA, A, aaaaaaa aaaaaa aaaaaa. 59; 51069 aöaa aA0a, A, aaa aaaaaaaaa Aa aaa aaaaaaüaaa 20A; 27721 aaaaaaaaaa aaaaaaaaaa aaaa aaa; 00001 aaaaaaüaaaaa aA0aaa, A, aaaa aaaa aaaaaaaaaaaaa 4; 27478 aaaaaaaa Aa Aaaaa aaaaa 2; 27472 aaaaaaaa aA0aaa, A, aaaaa Aaaa aöaaaaaaa. 27; 99734 aaaaaaaaaa (Editiert von user unknown - das sollte reichen).
|
user_unknown
Anmeldungsdatum: 10. August 2005
Beiträge: 17622
Wohnort: Berlin
|
Sorry - das war meine Unachtsamkeit - die Zeilen sind ja noch nicht umgebrochen - also wirft 'head' viel mehr Daten raus. Die Kundennummer ist also ein keine Nummer, zumindest keine dezimale, sondern mehr ein Identifier oder wie man das nennen will. Mit Umbrüchen sieht es wohl so aus - sicher kein Problem für die Perl-Fraktion:
aA0A, A, aaaa. aa. aaaa aaaaaaa aaaaaaa. 27; 49536 aaaaaa aA0Aa, A, aaaaaa aaaaaaa aaaaaaaaaaaa 2 a; 37085 aöaaaaaaa aA0Aaa, A, aa. aaaaaaa aaaaaaaaaa aaaaaaaaaa. 12; 66117 aaaaaaüaaaa aaaaaaaaaaaaaa; 66117 aaaaaaüaaaa aA0aAa, A, aaaaaaaaa aaaaa aA0aa, A, aaaaa aaaaaa aaaaaaaaa aaaaaaa 422; 44805 aaaaaa aA0aaa, A, Aaaaaaaaa aaaaa aaaaaaaa. 34; 96215 aaaaaaaaaaa aA0aA, A, aaaaa aaaaaa aaaaaaa 196; 48599 aaaaaa aaaaaaaaa. 28; 48599 aaaaaa aA0aa, A, aaa aaaaaaa aaaaaaaaaaaa 35; 03055 aaaaaaa aA0aaa, A, aaaaaaa aaaaa aaaaaaaa. 44; 45881 aaaaaaaaaaaaa aaaaaaaaaaaaa. 11; 48159 aüaaaaa aA0aa, A, aaaaaaa aaaaa aaaaaaaaaaaaa 9; 95652 aaaaaaaaaa aA0aaa, A, aaaaaaaa aaaaaa aA0aa, A, aüaaaaa aaaaa aaaaaaaaaa. 54; 01129 aaaaaaa aA0aaa, A, aa. aaaaaa aaaaa aaaaaaaaaa aaa. 14; 99086 aaaaaa aA0aaa, A, aaaaa aaaaaa aaaaaa aaa 1; 74653 aüaaaaaaa aA0a, A, aaaaaa aaaaaaaa aA0aa, A, aaaaa aaa aaaaaaaaa-aaaaa-aaa. 18; 36043 aaaaa aA0aaa, A, aaaaaaaa aaaaaaaaa aaaaaaaaaaaaaaa. 87; 98708 aaaaaa aA0aaa, A, aaaaaa aaaaaaa aaaaaaaa. 6; 90542 aaaaaaaa aA0aa, A, aaaaa aaaaaa aaaaaaaaaa aaa. 38; 15234 aaaaaaaaa / aaaa aaaaaaaaaaa. 7; 15236 aaaaaaaaa / aaaa aA0aa, A, aaaa.aa.aaa. aaa aaaa aaaaaaaaaaaa 7 a; 85567 aaaaaaa aA0aaa, A, aaaaaaaa aaaaaa aaaaa-aaaaa-aaa. 35; 50827 aöaa aA0aaa, A, aaaaaa aaaaaa-aaaaaaa aaüaa aaaaa 19; 15754 aaaaaaaa / aa aaaaaa aA0aaa, A, aaaaa aaaaaaaaaaa aaa aaaa 688; 27498 aaaaaaaaa aA0aa, A, aa. aaaaaa aaaaa aaaaaaaaaa aaa. 14; 99086 aaaaaa aA0aaa, A, aaaa. aa. aaaa aaaaaaa aA0a, A, aa. aaaaa aaaaaaaaaa aaa aaa aaaaaaaa 11; 49808 aaaaaa aA0aaa, A, aaaa aüaaa aaaaaaaaa 13; 66802 Üaaaaaaaa aaa. a. aaaaaaaaa- aaaaaa 1; 66287 aaaaaaaaaaa aA0aaA, A, aaaaaaa aaaaaa aaaaaa. 59; 51069 aöaa aA0a, A, aaa aaaaaaaaa Aa aaa aaaaaaüaaa 20A; 27721 aaaaaaaaaa aaaaaaaaaa aaaa aaa; 00001 aaaaaaüaaaaa ...
So wie es aussieht gibt es teilweise mehrere PLZ und auch sonstige Kuriositäten - aber der Kunden-ID sieht identifizierbar aus: [a-zA-Z]A0[a-zA-Z]*,
|
Weller
(Themenstarter)
Anmeldungsdatum: 10. Januar 2007
Beiträge: 104
Wohnort: Gebhardshain
|
So wie es aussieht gibt es teilweise mehrere PLZ und auch sonstige Kuriositäten - aber der Kunden-ID sieht identifizierbar aus: [a-zA-Z]A0[a-zA-Z]*,
Hallo! Hab' mich noch etwas damit beschäftigt: Also ([D][A-R][0-9][A-Z]+),\s([A-E]),\s([^;]+);\s(\d{5})\s(\w+) scheint einen Datensatz recht gut zu beschreiben... Aber wie jetzt in CSV zwängen??? Gruß, Andreas Weller
|
xoanon
Anmeldungsdatum: 12. Dezember 2006
Beiträge: 121
Wohnort: Hamburg
|
mit s/([D][A-R][0-9][A-Z]+),\s([A-E]),\s([^;]+);\s(\d{5})\s(\w+)/$1,$2,"$3",$4,"$5"\n/ ... das reicht normalerweise. Ansonsten gibs für Perl noch sehr schöne CPAN Module die sich auch ums " und ; escapen kümmern (es gibt da gewisse "standards" die ich aber nicht so 100%ig kenne). DBI Treiber: DBD::CSV mag ich recht gerne. Mann arbeitet mit SQL Befehlen auf CSV Tabellen - Sehr schön wenn's grösser wird als man dachte und irgendwann sich sagt "so, jetzt aber richtig". Hat einen gewissen "overhead" da mann halt mit sql befehlen Zeilen einfügt. Hat sich bei mir aber schon rel. oft gelohnt. Ansonsten Text::CSV_XS... Wenn du überhaupt perl kannst/magst.
|
Sid_Burn
Anmeldungsdatum: 23. Oktober 2004
Beiträge: 2159
|
Ansonsten gibs für Perl noch sehr schöne CPAN Module die sich auch ums " und ; escapen kümmern (es gibt da gewisse "standards" die ich aber nicht so 100%ig kenne).
Wenn ein Semikolion im Datensatz vorkommt, dann wird der Datensatz mit Anführungszeichen begrenzt. Beispiel:
"<datensatz>";<datensatz>;<datensatz>;"<datensatz>" Sollte ein Anführungszeichen danach im Datensatz auftreten, dann wird das Anführungszeichen durch zwei Anführungszeichen escaped. beispiel:
"Er sagte; ""Hallo""";foo;bar;"hallo; Welt" Das Beispiel hat 4 Datensätze. 1) Er sagte; "Hallo" 2) foo 3) bar 4) hallo; welt Man sieht immer wieder Falsche Lösungen wo einfach Sinnlos an ";" getrennt wird, oder wo man beim Schreiben nicht beachtet ob ein Semikolion im Datensatz vorkommt. Vorallem bei den Bash Leuten sehr beliebt. Anhand dieses Beispiel sieht man eigentlich schon das der Aufwand komplex genug ist was die Verwendung von Modulen rechtfertig. Und zweitens. Das deine Substitution ebenso Falsch ist, und diese Sonderfälle nicht beachtet. P.S.: Es gibt natürlich unterschiedliche Trennzeichen und Möglichkeiten CSV Dateien zu Beschreiben, auch kann das Escapen durch en Backslash vorkommen. Oder es werden wirklich mal Kommata verwendet anstatt Semikolions. 😉 Aber Semikolion und das Anführungszeichen durch zwei aufeinanderfolgende zu Escapen ist so schon weit verbreitet. Es ist z.B. auch das Format das OpenOffice.org Calc Standardmäßig so akzeptiert.
|