Autor
|
Thema: schwieriges csv lesen
|
silicon
AErodynamic
Usernummer # 503
|
verfasst
Hi Leute,
Ich muss ein relative kompliziertes CSV (nicht wirklich) auslesen.
10'PIA+5+000000000000001200'IMD+F++:::ExpressIdent bis 1 kg'MEA+WT+AAE+KGM:0.500'QTY+129:1:NPL'QTY+47:1:NPL'MOA+203:19.17'PRI+CAL:19.17:::1:15'RFF+ON:240825'RFF +AAM:P853793106366'DTM+95:20030811:102'TAX+7+VAT++ C4+:::16.000'MOA+150:3.07'NAD+CN+0000180630++MUSTERMANN MAX+MUSTERSTR. 2+MUSTERSTADT++80331+DE'ALC+A++++SH:::Nettowert'LI N+
Das ganze ist eine Zeile lang und wird nach LIN+ mit einem Zeilenumbruch getrennt. Danach gehts weiter mit dem nächsten Kundendatensatz.
Hab das in C mit fscanf versucht, a la http://www.pronix.de/C/standard_C/c...ng_19_1.shtml#9
Jedoch hab ich das Problem, dass z.B. an erster Stelle die 10 die Position ist und automatisch hochzählt, name ist ja auch immer verschieden lang usw.
desweiteren weiss ich nicht, was c da mit den ganzen + und ' anstellt. hab das mal mitm gdb debugged, aber sieht schlecht aus. hier mal bißchen code:
code:
while((fscanf(CSV," %s'PIA+5+000000000000001200'IMD+F++:::ExpressIdent bis 1 kg'MEA+WT+AAE+KGM:0.500'QTY+129:1:NPL'QTY+47:1:NPL'MOA+203:19.17'PRI+CAL:19.17:::1:1 5'RFF+ON:%s'RFF+AAM:%s'DTM+95:20030811:102'TAX+7+V AT++C4+:::16.000'MOA+150:3.07'NAD+CN+ZILL MARIO+LEHMANNSTR. 30+DRESDEN++%s+DE'ALC+A++++SH:::Nettowert'LIN+\n" ,&position, &cust_key, &paket_nr, &plz)) != EOF ) { fprintf(stdout,"%s;%s;%s;%s;\n",position, cust_key, paket_nr, plz); } return 0;
oder vielleicht hat jemand ne bessere lösung.
cheers, silicon
Aus: Universe | Registriert: May 2000
| IP: [logged]
| |
|
|
mik
   
Usernummer # 5095
|
verfasst
Das mit der unterschiedlichen Größe bei Namen sollte eigentlich kein Problem sein, da CSV-Dateien normalerweise ein eindeutiges Trennzeichen zwischen den einzelnen Positionen haben.
Aus: Altendorf | Registriert: Feb 2002
| IP: [logged]
| |
|
|
minimalniemand
 217cup 2oo4
Usernummer # 3401
|
verfasst
sieht mir danach aus, als wenn das + das Trennezeichen ist ... Je nach dem was Du mit den Daten machen willst würd ich Dir profanerweise einfach mal Excel empfehlen. Es sei denn du musst Die Daten irgendwie softwaremäßig auswerten/aufbereiten
muss es denn unbedingt C sein?
Aus: echtem Leder | Registriert: Aug 2001
| IP: [logged]
| |
|
|
Braindrain
   
Usernummer # 629
|
verfasst
in PHP koennte man das csv per
$dateizeilen=file($pfad_zur_csv_datei);
befehl zeilenweise einlesen und dann mit
$felder = explode ("+", $dateizeilen);
die felder (+ ist trennzeichen) in ein array lesen.
sowas aehnliches wird es auch in C geben, die syntax ist ja verwand.
Aus: FFM [x] NRW[] | Registriert: Jun 2000
| IP: [logged]
| |
|
|
silicon
AErodynamic
Usernummer # 503
|
verfasst
@minimal:
Nein, muss es nicht, aber kein
-C++ -Java
alles andere was auf unserer Solaris Maschine nicht schon drauf ist. PHP z.B. auch nicht, weil das n Cronjob werden soll.
Es ist z.T. mit + getrennt, aber manche Positionen sind für mich total ungeeignet. Das soll ne Vorbereitung fürn SQL-Loader werden.
Schwierig schwierig, ich seh schon, ich werd mich zeichenweise durchkämpfen müssen.
cheers, silicon
Aus: Universe | Registriert: May 2000
| IP: [logged]
| |
|
|
minimalniemand
 217cup 2oo4
Usernummer # 3401
|
verfasst
Du kannst dir in VBA n kleines Tool schreiben das Dir die Datei einliest und ne txt-Datei mit nem fertigen SQL-Insert-Statement ausgibt... das würde ich zumindest mit meiner geilen High-End Programmiersprache machen
Aus: echtem Leder | Registriert: Aug 2001
| IP: [logged]
| |
|
|
silicon
AErodynamic
Usernummer # 503
|
verfasst
@minimalniemand: Das krieg ich mit C auch hin und der Code ist dann wahrscheinlich 100x schneller als der VBA-Code. Das Problem ist, ich brauch nur 4-5 Postionen in dem Ding.
Scheissendreck echt...
cheers, silicon
Aus: Universe | Registriert: May 2000
| IP: [logged]
| |
|
|
Neuro
   
Usernummer # 883
|
verfasst
PHP lässt sich auch ohne Webserver benutzen.
Wie wärs denn mit RegularExpressions, z.B. mit Perl oder sed, awk - Standardtools die genau für sowas gemacht sind und die es auf jedem UNIX-System gibt.
Man muss nicht für jedes Problemchen das Rad neu erfinden.
Aus: dead H-Town Ghetto | Registriert: Aug 2000
| IP: [logged]
| |
|
|
silicon
AErodynamic
Usernummer # 503
|
verfasst
Das Ding mit AWK? Hm, daran hab ich auch schon gedacht, aber mir grauts schon vor der Syntax
cheers, silicon
Aus: Universe | Registriert: May 2000
| IP: [logged]
| |
|
|
PigFace
500
Usernummer # 4299
|
verfasst
Hmm für mich sieht das eher so aus als ob der Doppelpunkt das Trennzeichen wäre. Das kannste mit einem relativ simplen Shell-Script aufdröseln sogar ganz ohne sed und awk, z. B.
code:
#!/bin/sh #
clear echo -e "--- Start ---\n"
# erzeuge Beispieldatei echo "10'PIA+5+000000000000001200'IMD+F++:::ExpressIdent bis 1 kg'MEA+WT+AAE+KGM:0.500'QTY+129:1:NPL'QTY+47:1:NPL'MOA+203:19.17'PRI+CAL:19.17:::1:15'RFF+ON:240825'RFF+AAM:P853793106366'DTM+95:20030811:102'TAX+7+VAT++C4+:::16.000'MOA+150:3.07'NAD+CN+0000180630++MUSTERMANN MAX+MUSTERSTR. 2+MUSTERSTADT++80331+DE'ALC+A++++SH:::Nettowert'LIN+" >allvals
sep=":" term="LIN+" valcount=1
for sv in "$(cat allvals)"; do echo "Wert "$valcount echo $sv >singleval colcount=1 col=`cut -d$sep -f1 singleval` # gib alle Werte bis auf den letzten aus while [ ! $(echo "$col" | grep "^.*"$term"$") ]; do echo $colcount" - "$col let colcount+=1 col=`cut -d$sep -f$colcount singleval` done # gib den letzten Wert aus echo $colcount" - "$col let valcount+=1 done
rm -f allvals rm -f singleval
echo -e "\n--- Ende ---"
Aus: Somewhere in the skeleton | Registriert: Nov 2001
| IP: [logged]
| |
|
|
minimalniemand
 217cup 2oo4
Usernummer # 3401
|
verfasst
das hiesse ja, dass Name & Strasse im gleichen Feld stünden. Halte ich für unwarscheinlich. Der Doppelpunkt ist imho nur ein Platzhalter...
Aus: echtem Leder | Registriert: Aug 2001
| IP: [logged]
| |
|
|
chickonspeed
  
Usernummer # 10575
|
verfasst
gehe ich richtig davon aus das ' und + trennzeichen sind? weil dann unterteilt ' die strings in gruppen, wenn man das so nennen kann und die + trennen die komponenten in der gruppe.
hab hier auch mal nen stück code
code:
int main(int argc, char* argv[]) { string text = "10'PIA+5+000000000000001200'IMD+F++:::ExpressIdent bis 1 kg'MEA+WT+AAE+KGM:0.500'QTY+129:1:NPL'QTY+47:1:NPL'MOA+203:19.17'PRI+CAL:19.17:::1:15'RFF+ON:240825'RFF+AAM:P853793106366'DTM+95:20030811:102'TAX+7+VAT++C4+:::16.000'MOA+150:3.07'NAD+CN+0000180630++MUSTERMANN MAX+MUSTERSTR. 2+MUSTERSTADT++80331+DE'ALC+A++++SH:::Nettowert'LIN+"; string exStr = "LIN+"; string tmp;
string::size_type pos = 0;
cout << "Start..." << endl;
do { pos = text.find ("'",0); tmp = text.substr(0,pos);
//irgendwas mit tmp machen...
text.erase (0,pos+1);
} while( tmp != exStr );
cout << "Ende..." << endl;
return 0; }
man könnte das ganze aber auch als rekursive funktion behandeln...
ach ja ich weiß ist c++ ich schau das ich es nachher nochmal in c schreibe.
Aus: TÜ | Registriert: Aug 2003
| IP: [logged]
| |
|
|
silicon
AErodynamic
Usernummer # 503
|
verfasst
Leute ihr geht ja voll ab...danke! Häng grad noch woanders fest, stoße aber bald hier dazu.
cheers, silicon
Aus: Universe | Registriert: May 2000
| IP: [logged]
| |
|
|
chickonspeed
  
Usernummer # 10575
|
verfasst
hab dir hier nochmal das selbe in c und mit rekursion. allerdings muß ich sagen das es nur funktioniert. wenn du das verwenden willst solltest vorallem den speicherverbrauch optimieren. denn so is das ja nix
eigentlich müßte der quellcode auf deiner sun laufen da sämltliche funktionen in ansi-c implementiert sind.
code:
#include <string.h> #include <iostream.h>
//---------------------------------------------------------------------------
void parse( char *pText ) { int chars = 0; int exit = 0;
char tmp[64]; char textTmp[512]; int i;
memset( &tmp[0], 0, sizeof( tmp )); memset( &textTmp[0], 0, sizeof( textTmp ));
chars = strcspn( &pText[0], "'" ); // sucht nach wievielen zeichen ein ' kommt strncpy(&tmp[0], &pText[0], chars); // kopiert den teilstring
printf("_ %s\n", tmp);
if( strcmp( tmp, "LIN+" ) == 0 ) { return; }
//neuarragngieren des strings strcpy( &textTmp[0], &pText[0] );
for( i=chars; i<512; i++ ) { if( textTmp[i] != '\0' ) { pText[i-chars] = textTmp[i+1]; } else { break; } }
memset( &textTmp[0], 0, sizeof( textTmp ));
parse( pText ); }
int main(int argc, char* argv[]) { char text[512]; char exStr[4] = "LIN+"; char exChar[1] = "'";
memset( &text[0], 0, sizeof( text )); strcpy( text, "10'PIA+5+000000000000001200'IMD+F++:::ExpressIdent bis 1 kg'MEA+WT+AAE+KGM:0.500'QTY+129:1:NPL'QTY+47:1:NPL'MOA+203:19.17'PRI+CAL:19.17:::1:15'RFF+ON:240825'RFF+AAM:P853793106366'DTM+95:20030811:102'TAX+7+VAT++C4+:::16.000'MOA+150:3.07'NAD+CN+0000180630++MUSTERMANN MAX+MUSTERSTR. 2+MUSTERSTADT++80331+DE'ALC+A++++SH:::Nettowert'LIN+" );
parse( &text[0] );
Sleep(10000); return 0; }
Aus: TÜ | Registriert: Aug 2003
| IP: [logged]
| |
|
|
silicon
AErodynamic
Usernummer # 503
|
verfasst
Sleep und die Kommentare gingen bei mir nicht. Ansonsten sieht´s echt gut aus, mein Junge. Jetzt muss ich´s nur noch so umschreiben, dass die necessery values in eine explizites file geschrieben werden.
thx alot!!!!
cheers, silicon
Aus: Universe | Registriert: May 2000
| IP: [logged]
| |
|
|
chickonspeed
  
Usernummer # 10575
|
verfasst
bei fragen einfach posten. ich schau was ich dann tun kann!
Aus: TÜ | Registriert: Aug 2003
| IP: [logged]
| |
|
|
PigFace
500
Usernummer # 4299
|
verfasst
Mal unabhängig davon in welcher Programmiersprache man das realisiert und was das Trennzeichen ist: Mir ist grad eingefallen daß ich so eine Routine mal gecodet habe und da den Fall berücksichtigen musste dass das Trennzeichen möglicherweise in den Werten (als Teil derselben) auftreten konnte, in dem Fall waren betroffene Werte dann von Anführungszeichen eingeschlossen (ich glaub Excel macht das auch so wenn man nach .csv exportiert und das Trennzeichen ';' in Zellen der Tabelle hat). Check mal ob so was bei dir auch der Fall sein könnte, wenn ja wird die Lösung wohl ein wenig komplizierter aussehen müssen.
Aus: Somewhere in the skeleton | Registriert: Nov 2001
| IP: [logged]
| |
|
|
philipp
Usernummer # 687
|
verfasst
Sorry aber das rekursiv zu machen ist abartig - anders kann mans nicht nennen... Mach nie etwas rekursiv es sei denn es geht nicht anders (und es geht immer anders) oder es handlet sich um irgendeine wissenschaftliche Fingerübung! Im Produktivbereich blos die Finger davon lassen! Bitte!
(Sowas müssen Leute wie ich dann ausbaden *g*)
Aus: Essen | Registriert: Jul 2000
| IP: [logged]
| |
|
|
silicon
AErodynamic
Usernummer # 503
|
verfasst
Tja, die POST halt!*g*
cheers, silicon
Aus: Universe | Registriert: May 2000
| IP: [logged]
| |
|
|
Thomas Broda
BassFiMass PhonkAggressor
Usernummer # 72
|
verfasst
Zitat: Ursprünglich geschrieben von: Neuro:
Wie wärs denn mit RegularExpressions, z.B. [...] sed, awk - Standardtools die genau für sowas gemacht sind und die es auf jedem UNIX-System gibt.
Würd ich auch dringend empfehlen, denn mit Regulären Ausdrücken könntest Du bereits über den Suchstring den kompletten Datensatz formatiert ausgeben - bequemer geht's nicht.
Fürchte nur, die Windows-Shell kann u.a. auch keine Regulären Ausdrücke...
Aus: Jux und Dollerei | Registriert: Dec 1999
| IP: [logged]
| |
|
|
silicon
AErodynamic
Usernummer # 503
|
verfasst
@Thomas Broda:
Nix Windows-Shell. Ich arbeite auf Solaris. Ich müsste mich da aber erstmal in awk einlesen und das ist echt heftig, vorallem diese Syntax bei der eh schon so zermürbten Rohdatei.
Gute Tutorials are welcome...
cheers, silicon
Aus: Universe | Registriert: May 2000
| IP: [logged]
| |
|
|
|
f_bohmann
  
Usernummer # 4920
|
verfasst
was ich daran nicht so ganz schnalle:
beispielzeile aus deinem text:
NAD+CN+0000180630++MUSTERMANN MAX+MUSTERSTR. 2+MUSTERSTADT++80331+DE
zeile aus deinem code:
NAD+CN+ZILL MARIO+LEHMANNSTR. 30+DRESDEN++%s+DE
das plus scheint n trennzeichen zwischen den einzelnen inhalten der felder zu sein. ABER: die inhalte beiden zeilen haben underschiedliche indizes. dh. der name steht in beiden zeilen an unterschiedlicher stelle... hast du dich da einfach vertippt, oder sind das beides daten aus dem selben csv?
edit: das ganze ist nach n bisschen webrecherche scheinbar einfach nur ein logistik.standardformat names EDIFACT ... die post an sich hat das also nicht verbrochen.
http://www.edifactory.de/index.html (da gibts n c-parser) http://www.unece.org/trade/untdid/welcome.htm (da gibts viel zu viel text)
Aus: Bingen am Rhein | Registriert: Feb 2002
| IP: [logged]
| |
|
|
silicon
AErodynamic
Usernummer # 503
|
verfasst
@f_bohmann: Ja das stimmt, da hab ich wohl die frachtbrief_nr vergessen. aber was soll´s, habs ja jetzt umgeschrieben.
thx für die recherche, wäre nicht nötig gewesen. ich weiss was das ist, jedoch wollte ich das nicht hier so ausführen. aber ich denke an einer kommerziellen lösung ist mein chef nicht interessiert.
edit: hab jetzt den 'tiny-converter' gefunden. sehr geil, danke! hoffe ich kann damit was anfangen.
nochmal danke an alle die so fleißig mitgeholfen haben. hätte vielleicht doch früher gleich nach EDIFACT grep..ähh googlen sollen.
aber noch ists noch nicht ganz fertig. das problem an einem selbstgeschriebenen c code ist, falls sich mal eine nachricht ändern sollte, läuft das ganze import schief und man hätte monatlich ärger.
cheers, silicon
Aus: Universe | Registriert: May 2000
| IP: [logged]
| |
|
|