This is topic schwieriges csv lesen in forum Produktions- & DJ-Technik, Hard- & Software at technoforum.de.


Um den Thread anzusehen, klicke auf diesen Link:
https://forum.technoforum.de/cgi-bin/ultimatebb.cgi?ubb=get_topic;f=6;t=005242

Geschrieben von: silicon (Usernummer # 503) an :
 
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
 
Geschrieben von: mik (Usernummer # 5095) an :
 
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.
 
Geschrieben von: minimalniemand (Usernummer # 3401) an :
 
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?
 
Geschrieben von: Braindrain (Usernummer # 629) an :
 
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.
 
Geschrieben von: silicon (Usernummer # 503) an :
 
@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
 
Geschrieben von: minimalniemand (Usernummer # 3401) an :
 
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 [smilesmile]
 
Geschrieben von: silicon (Usernummer # 503) an :
 
@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
 
Geschrieben von: Neuro (Usernummer # 883) an :
 
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.
 
Geschrieben von: silicon (Usernummer # 503) an :
 
Das Ding mit AWK? Hm, daran hab ich auch schon gedacht, aber mir grauts schon vor der Syntax [angst]

cheers,
silicon
 
Geschrieben von: PigFace (Usernummer # 4299) an :
 
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 ---"

[piggy]
 
Geschrieben von: minimalniemand (Usernummer # 3401) an :
 
das hiesse ja, dass Name & Strasse im gleichen Feld stünden. Halte ich für unwarscheinlich. Der Doppelpunkt ist imho nur ein Platzhalter...
 
Geschrieben von: chickonspeed (Usernummer # 10575) an :
 
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.
 
Geschrieben von: silicon (Usernummer # 503) an :
 
Leute ihr geht ja voll ab...danke! [lachlach]
Häng grad noch woanders fest, stoße aber bald hier dazu.

cheers,
silicon
 
Geschrieben von: chickonspeed (Usernummer # 10575) an :
 
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 [Wink]

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;
}


 
Geschrieben von: silicon (Usernummer # 503) an :
 
Sleep und die Kommentare gingen bei mir nicht. Ansonsten sieht´s echt gut aus, mein Junge. [top] Jetzt muss ich´s nur noch so umschreiben, dass die necessery values in eine explizites file geschrieben werden.

thx alot!!!! [gluecklich]

cheers,
silicon
 
Geschrieben von: chickonspeed (Usernummer # 10575) an :
 
bei fragen einfach posten. ich schau was ich dann tun kann!
 
Geschrieben von: PigFace (Usernummer # 4299) an :
 
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. [rolleyes]

[piggy]
 
Geschrieben von: philipp (Usernummer # 687) an :
 
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*)
 
Geschrieben von: silicon (Usernummer # 503) an :
 
Tja, die POST halt!*g*

[winke]

cheers,
silicon
 
Geschrieben von: Thomas Broda (Usernummer # 72) an :
 
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...
 
Geschrieben von: silicon (Usernummer # 503) an :
 
@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
 
Geschrieben von: mik (Usernummer # 5095) an :
 
Tutorial für AWK:

[hand] AWK

Tutorials für SED:

[hand] SED-Teil1
[hand] SED-Teil2
 
Geschrieben von: f_bohmann (Usernummer # 4920) an :
 
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. [Smile]

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) [Wink]
 
Geschrieben von: silicon (Usernummer # 503) an :
 
@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.

[tutmirleid]

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
 



(c) 1999/2ooo/y2k(+1/+2/+3+4+5+6+7+8+9+2010+2011+2012+2013+2014+2015+2016+2017+2018+2019+2020+2021+2022+2023+2024) technoforum.de | www.techno-forum.de
Das Forum für Techno | House | Minimal | Trance | Downbeats | DnB | Grime | Elektro | IDM | Elektronika | Schranz | MNML | Ambient | Udio.ai | Dub | 2Step | Breakcore | no Business Techno | Dubstep | Big Room Techno | Grime | Complextro | Mashups | mnml | Bootlegs | Chicago House | AI Music Suno | Acid House | Detroit Techno | Chillstep | Arenastep | IDM | Glitch | Grime | Experimental | Noise | Fidgethouse | Ableton Live 12 | Melbourne Bounce | Minimal Trap | Sinee | kvraudio alternative | EDM | Splice | Bandcamp Soundcloud | Free Techno Music Download | Progressive Electro House | Free VSTi |
Betreiberangaben & Impressum siehe readme.txt, geschenke an: chris mayr, anglerstr. 16, 80339 münchen / fon: o89 - 5oo 29 68-drei
E-Mail: webmaster ät diesedomain
similar sites: www.elektronisches-volk.de | Ex-Omenforum | techno.de | USB | united schranz board | technoboard.at | technobase | technobase.fm | technoguide | unitedsb.de | tekknoforum.de | toxic-family.de | restrealitaet restrealität | boiler room
Diese Seite benutzt Kuhkies und du erklärst dich damit bei Betreten und Benutzung dieser Seite damit einverstanden. Es werden keinerlei Auswertungen auf Basis ebendieser vorgenommen. Nur die Foren-Software setzt Kuhkies ausschließlich für die Speicherung von Nutzerdaten für den einfacheren Logon für registrierte Nutzer, es gibt keinerlei Kuhkies für Werbung und/oder Dritte. Wir geben niemals Daten an Dritte weiter und speichern lediglich die Daten, die du uns hier als Nutzer angegeben hast sowie deine IP-Adresse, d.h. wir sind vollkommen de es fau g o-genormt, nixdestotrotz ist das sowieso eine PRIVATE Seite und nix Gewerbliches.


Powered by Infopop Corporation
UBB.classicTM 6.5.0