Einlesen CSV File (bestehend aus 6 Coloums)

  • Hallo zusammen,

    da mir irgendwie die zündende Idee fehlt und ich es mit AutoIT nicht gebacken bekomme - wende ich mich hier an die 'Profis' - Danke schon mal im voraus.
    (P.S: mittels Powershell hat das relative einfach funktioniert (Code füge ich unten bei)


    Problem:
    Ich muss (tausende) kleine Textdateien erzeugen, die alle den gleichen Aufbau haben und als Quelle eine csv Datei nutzen (diese werfe ich automatisiert aus).

    Quelle:
    Format der csv Datei wie folgt:
    Header: Redirect,Order, RID, Titel, Ref, Filename
    Data: [NRF], Order=Sequential,RID=1111111111122232321,Titel=Angela Merkel,Ref=CN=XXX/OU=YYY/O=ZZ!!abc\n631.xyz, n6361.xyz
    .....


    Ziel (1 Datei pro Zeile) - wobei der letzte Wert den Dateinamen darstellt

    Also:
    Datei n6361.nrf mit folgendem Inhalt
    [NRF]
    Order=Sequential
    RID=1111111111122232321
    Titel=Angela Merkel
    Ref=CN=XXX/OU=YYY/O=ZZ!!abc\n631.xyz


    Das Ganze gelingt mir schon - wenn ich im Vorfelde aus den Zeilen der CSV Datei jeweils untereinander stehende einzelne Werte in einer Spalte mache
    [NRF]
    Order=Sequential
    RID=1111111111122232321T
    itel=Angela Merkel
    Ref=CN=XXX/OU=YYY/O=ZZ!!abc\n631.xyz
    n6361.nrf


    Daher meine Frage wie gelingt mir das Einlesen der 'Zeilen' und das Umsetzen in untereinander stehende einzelne Werte.
    (Anm.: im Script wird auch noch ein batch fürs Kopieren erzeugt - ist aber nicht Teil der Frage)


    HIer mein Script

    Spoiler anzeigen


    #include <Array.au3>
    #include <File.au3>
    AutoItSetOption('TrayIconDebug', 1)

    Local $acdeNRF

    $cdeMessage = "Bitte das Quellfile (zwingend Format Textfile) angeben"
    $cdeSourceNRF = FileOpenDialog($cdeMessage,@ScriptDir & "\", "Textfile (*.txt;*.csv)",1,"") ;QuellFile angeben für XXX's
    If @error = 1 Then Exit ;Cancel-Button

    $cdeTargetLW = InputBox("Server Ziel-LW","Gemapptes DominoServer Ziel LW angeben:", "Z:\","",250,140) ;Ziel LW der Maschine
    If @error = 1 Then Exit ;Cancel-Button

    If Not _FileReadToArray($cdeSourceNRF, $acdeNRF) Then
    MsgBox(4096, "Fehler", " Fehler beim Einlesen ins Array (Error:" & @error &")") ;Einlesen Sourcefile mit Errorhandling (Öffnen des Datenfiles)
    Exit
    EndIf

    $CdeRuns = $acdeNRF[0]/6 ;Berechnung der Anzahl zu erzeugender Files (1-6 Zeilen = Dateiinhalt / 6.Zeile Filename)
    If Int($CdeRuns) - $CdeRuns <> 0 Then
    MsgBox(16,"In der Quelldatei liegt ein Fehler vor","Wahrscheinlichster Fehler: Ein falsche Anzahl an Datenzeilen" & @LF & @LF & "Richtig sind:" & @LF & "5 Zeilen Daten + 1 Zeile für Dateinamen (6 Zeilen/nrf file).")
    Else ;Errorhandling (Anzahl Zeilen muss aufgehen / durch 6 teilbar)
    $cdeMessage1 = ""
    SplashTextOn("Autom. Dateierstellung - Step 1", $cdeMessage1, 300, 70, -1, -1, 16+2, "", 10, 400) ;Splash
    For $i = 1 To $CdeRuns ;Schleife .... Start
    FileOpen(@ScriptDir & "\nrf_temp.txt",2) ;Temp File erzeugen
    For $x = 1 To 5
    _FileWriteToLine(@ScriptDir & "\nrf_temp.txt", $x, $acdeNRF[$x], 1) ;Schreiben der 5 Zeilen für NRF in das neues Temp File
    If $x = 5 Then
    $cdeTestFilenamePos = StringInStr($acdeNRF[$x], "\", 0, -1)
    $cdeTestFileLen = StringLen($acdeNRF[$x])
    $cdeTestFileonly = $cdeTestFileLen - $cdeTestFilenamePos
    $cdeTestFilename = StringRight($acdeNRF[$x],$cdeTestFileonly)
    $cdeTestFilenameNoExt = StringTrimRight($cdeTestFilename, 3)
    EndIf

    Next
    FileClose(@ScriptDir & "\nrf_temp.txt")
    $cdeFilename = $cdeTestFilenameNoExt & "nrf" ;Dateiname ermitteln (immer die jeweils 6.Zeile)
    FileMove(@ScriptDir & "\nrf_temp.txt",@ScriptDir & "\nrf\" & $cdeFilename,9) ;Neues File benamen und ins Verzeichnis 'NRF' schieben
    $cdeMessage1 = ($i & " / " & $CdeRuns & " - NRF File(s) erzeugt" & @CRLF & @CRLF & $cdeFilename) ;Splash text
    ControlSetText("Autom. Dateierstellung - Step 1", "", "Static1", $cdeMessage1) ;Splash update
    Sleep(200)
    For $y = 1 To 5
    _ArrayDelete($acdeNRF, 1) ;'Abgearbeitete Zeilen' aus dem Array löschen
    Next
    Next ;Schleife .... Ende
    Sleep(500)
    _FileReadToArray($cdeSourceNRF, $acdeNRF) ;SourceFile erneut einlesen
    $x = 5
    SplashTextOn("- @cde/spi (2013) - Step 2", $cdeMessage1, 300, 70, -1, -1, 16+2, "", 10, 400) ;Splash
    For $i = 1 To $CdeRuns ; Schleife .... Start
    $cdeFileNameNew = $cdeTestFilenameNoExt & ".bat" ;Filename neu ->'Filename.bat'
    $z = StringInStr($acdeNRF[$x],"!", 0, -1) ;StringSplit - nach ! -von links- suchen (Ref=CN=XXXXXX/OU=YYYYY/O=ZZZZZ!!123\456\789.xxx)
    $cdePath = StringTrimLeft($acdeNRF[$x],$z) ;StringSplit - Anteil nach dem ! ermitteln (databases\EC\a3m.nsf)
    $cdeLenPath = StringLen($cdePath) ;StringSplit - Länge des 'Path' Strings ermitteln
    $z = StringInStr($cdePath,"\", 0, -1) ;StringSplit - nach \ -von links- suchen
    $z = $cdeLenPath - $z ;StringSplit - Ermitteln der Anzahl zeichen des 'Pfades'
    $cdePath = StringTrimRight($cdePath, $z+1) ;StringSplit - zusammensetzen Pfad (databases\EC)
    $cdeMessage1 = ($i & " / " & $CdeRuns & " - Batch File(s) erzeugt" & @CRLF & @CRLF & $cdeFileNameNew) ;Splash text
    ControlSetText("- @cde/spi (2013) - Step 2", "", "Static1", $cdeMessage1) ;Splash update
    Sleep(200)
    $cdeTemp = FileOpen(@ScriptDir & "\nrf\" & $cdeFileNameNew,2) ;Neues File mit FileNameNew erzeugen
    FileWrite($cdeTemp, "Copy " & ".\" & $cdeFilename & " " & $cdeTargetLW & "Notesdat\" & $cdePath) ;Ins File copy Zeile schreiben (copy Quelle - LW+Pfad)
    FileClose($cdeTemp)
    $x = $x + 6 ;Um 6 Elemente im Array weitergehen (nächster Dateiname)
    Next ;Schleife .... Ende
    EndIf
    Exit


    Wahrscheinlich ganz einfach .... für den 'Profi'


    und hier die Powershell

  • Ich nochmal ... um die Sache z u vereinfachen.

    Wie bewerkstellige ich es aus dem CSV File (den Zeilen) ---> die Einzeldateien mit den untereinander stehenden Werten (Zeilen) z u erzeugen
    (Im Prinzip könnte man auch sagen wie transponiere ich ich die Zeile(n) in Spalte(n))


    Danke schon mal im voraus

  • Hallo Chesstiger,

    da hast Du absolut recht.
    Aber da ich diese Art von 'Aufbereitung' verschiedenster CSV Files immer wieder machen muss (Analyse Logffiles ... etc),
    war/ist mein persönlicher Ehrgeiz das auch mit AutoIT lösen/abbilden zu können (da dieses mir eigentlich mehr zusagt als die Powershell).

    Auf Verständnis hoofend

    Danke
    mfg
    ugt100

  • so könnte man es machen... quick and dirty...

    Spoiler anzeigen
    [autoit]


    #include <Array.au3>
    #include <File.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Dim $aCSV, $aLine_Temp
    _FileReadToArray("data.csv",$aCSV)
    ;~ _ArrayDisplay($aCSV)

    [/autoit] [autoit][/autoit] [autoit]

    For $i = 1 to $aCSV[0]
    $aLine_Temp = StringSplit($aCSV[$i],",")
    ;~ _ArrayDisplay($aLine_Temp)
    $hfile = FileOpen($aLine_Temp[6], 1)

    [/autoit] [autoit][/autoit] [autoit]

    If $hfile = -1 Then
    MsgBox(0, "Fehler", "Die Datei konnte nicht geöffnet werden.")
    Exit
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    For $ii = 1 to $aLine_Temp[0]
    FileWrite($hfile, $aLine_Temp[$ii] & @CRLF)
    Next

    [/autoit] [autoit][/autoit] [autoit]

    FileClose($hfile)
    Next

    [/autoit]
  • Hi,
    um die Spalten in Zeilen zu transponieren musst du lediglich den Separator durch ein CRLF ersetzen

    [autoit]


    ;CSV BeispielDatei erstellen
    $text = "[NRF], Order=Sequential,RID=1111111111122232321,Titel=Angela Merkel,Ref=CN=XXX/OU=YYY/O=ZZ!!abc\n631.xyz, n6361.xyz" & @CRLF & _
    "[NRG], Order=Sequential,RID=9999992239999232321,Titel=Karla Kowalski,Ref=CN=YYY/OU=ZZZ/O=ZZ!!abc\n567.xyz, n5667.xyz" & @CRLF & _
    "[NRH], Order=Sequential,RID=7777777239999232321,Titel=Freddy Kruger,Ref=CN=ZZZ/OU=ZZZ/O=ZZ!!abc\n568.xyz, n5668.xyz"

    [/autoit][autoit][/autoit][autoit]

    $csv_datei = "Data.csv" ;Dateiname
    FileDelete($csv_datei) ;datei löschen
    FileWrite($csv_datei, $text) ;Datei erstellen

    [/autoit][autoit][/autoit][autoit]

    ;CSV einlesen und verarbeiten
    $csv_inhalt = FileRead($csv_datei) ;einlesen
    $csv_inhalt = StringReplace($csv_inhalt, ", ", ",") ;leerzeichen nach dem Komma löschen
    $csv_Zeilen = StringSplit($csv_inhalt, @CRLF, 3) ;zeilenweise trennen

    [/autoit][autoit][/autoit][autoit]

    For $csv_zeile In $csv_Zeilen ;alle Zeilen durchlaufen
    $csv_zeilen_replace = StringReplace($csv_zeile, ",", @CRLF) ;in jeder Zeile komma mit enter ersetzen
    $dateiname = StringTrimLeft($csv_zeilen_replace, StringInStr($csv_zeilen_replace, @CRLF, 1, -1) + 1) ;bis zur letzten Zeile alles abschneiden
    FileDelete($dateiname) ;datei löschen
    FileWrite($dateiname, $csv_zeilen_replace) ;Dateien schreiben
    Next

    [/autoit]
  • Hallo zusammen,

    Danke für die diversen Tips bzw. Anstösse. Die haben mir sehr geholfen - Danke
    Letztlich war es ja ganz offensichtlich mein Problem mit dem Ersetzen der Kommatas durch CRLF zu lösen.
    Manchmal sieht man halt den Wald vor lauter Baum nicht mehr.

    Jedenfalls ersetze ich jetzt die Kommas und gut ist es .

    Herzlichen Dank
    mfg
    ugt100

    :rock::thumbup::rock: