Hilfe für einen Anfänger beim automatischen Umschreiben/Umformatieren von Textdateien (Bildkoordinaten usw.)

  • Hallo, ich hoffe, Ihr könnt mir weiterhelfen und seid auch gewillt, das zu tun ;) ...
    Ich stehe oft vor der leidlichen Problematik, Nootepad++ als Spalteneditor für Textdateien zu verwenden.
    Dabei ähneln sich viele der Vorlagen, was die Positionierung der einzelnen Werte in der Datei angeht.
    Ich selbst würde mich als sehr unerfahren mit der Programmierung bezeichnen, lediglich ein mit viel Unterstützung entstandenes
    kleines Programm zur Änderung von Netzlaufwerten in einem GUI, AutoIt Tut´s (Einfachste Grundlagen, GUI, "Taschenrechner", beschränktes Dateihandling)
    + die Videos auf Youtoube und Tagelanges studieren und verstehen wollen von anderen Skrippten stehen auf der Haben Seite.
    Leider komme ich mit meinem bescheidenen Wissen nicht so richtig vom Fleck und hoffe, ihr könnt mich unterstützen.
    Hoffentlich poste ich das hier so richtig, wenn nicht, gebt mir bitte entsprechende Hinweise.

    Hier meine Problematik:
    Umeditieren von Txt-Dateien, von test.alt in eine neu erstellte test.neu.

    Ausgangssituation: Alle Einträge in den Ausgangstextdateien können verschieden sein, lediglich die Position (Zeile und Spalte) liegt fest

    Altes Format (test.alt):

    0 1 2 3 4
    1234567890123456789012345678901234567890 (Spalten):
    -abcd123 xab666 cd777 4 "Fußball Bernd"
    -abef456 xab888 ef999 8 "Tennis Silke"


    Neues Format (test.neu):
    0 1 2 3 4
    1234567890123456789012345678901234567890 (Spalten):
    + bd123 ab666 cd777 4 "Fußball Bernd"
    + bf456 ab888 ef999 8 "Tennis Silke"

    "Vermutlicher"/geplanter Programmdurchlauf

    Kleines GUI zur Steuerung
    -Auswahl der test.alt
    -Erstellung einer leeren test.neu im selben Verzeichniss wie die test.alt
    -Positionsweises einlesen der Werte von alt nach neu
    -schreibe in die neu Zeile 1 Spalte 1 ein +
    ...
    -schreibe in die neu Zeile 1 Spalte 4 den Wert von alt Zeile 1 Spalte 17
    ...
    -speichern der test.neu + Info zur Umsetzung
    Die Zahlen und der Bereich in " " in meinem Beispiel blieben identisch, nur halt an anderer Stelle.
    Meine Gedanken bisher dazu:

    Meine Baustellen:
    Ich hab es so versucht, das $avar den Pfad zur test.alt enthält. Wie kriege mittels der Variable im selben verzeichniss die leere test.neu erstellt ?
    Um die Werte einzeln zu überführen, müsste mann vermutlich für jeden Wert eine eigene Befehlszeile machen, oder wie kann ich auch Blöcke übernehmen ?
    Wie ich die einzelnen Positionen auslesen kann, hab ich noch keinen Schimmer :( ...
    Wenn ich da einmel weiß, wie es für 1 Feld (und ev. einen Block) geht, bekomme ich hoffentlich den Rest alleine hin.
    Nach langer Suche bin ich auch auf eine mögliche Exel-Anbindung gestoßen, bei derartigen Vorhaben. Mir wäre Exelfrei jedoch mehr als deutlich lieber ...
    Ist es überhaupt sinnvoll, wie gedacht zu arbeiten oder gibts einen besseren Weg ?
    Danke erstmal an alle, die sich überhaupt bis hier hin durchgekämpft haben ...
    Und jetzt : Hilfe ?(

    • Offizieller Beitrag

    So ein umkonvertieren geht doch recht problemlos. Einlesen, etwas mit StringReplace bzw. StringRegExReplace hantieren und dann wieder schreiben.
    Das sind nur ein paar Zeilen:

    [autoit]


    $sText = FileRead(@ScriptDir & '\test.txt')
    $sText = StringReplace($sText, '-', '+ ') ; 1. Schritt: alle Minuszeichen in Pluszeichen mit zusätzlichem Leerzeichen
    $sText = StringRegExpReplace($sText, '(\+ ).(.).(.)', '$1$2$3') ; 2. Schritt: die Formatierung im ersten Block ändern
    $sText = StringRegExpReplace($sText, '(\+ .{6}).(.+)', '$1$2') ; 3. Schritt: die Formatierung im zweiten Block ändern
    $hFile = FileOpen(@ScriptDir & '\text_neu.txt', 2) ; Datei "text_neu.txt" zum schreiben öffnen
    If $hFile <> -1 Then ; wenn erfolgreich, dann...
    FileWrite($hFile, $sText) ; neuen Text schreiben
    FileClose($hFile) ; Datei schließen
    EndIf

    [/autoit]
  • Ha, super! Das liest sich so, als wäre es genau dass, was ich da gesucht habe. Und viel einfacher, als erwartet (keine Zeilenweisen Abfragen/Schleifen...).
    Durch die ganzen Parameter wusel ich mich via Hilfe durch, bis ich alles drinn hab. Sollte ich hinkriegen, die test-Dateien waren ja zur Vereinfachung stark verkleinert...
    Vielen Dank @ OScar ! :thumbup:

    Ausführend ist es momentan ja im Skriptverzeichniss. Wenn ich meine Variable "$avar" richtig verstanden habe, sollte Sie ja den Pfad zur Quelldatei enthalten.Somit müsste ich "$avar" dann ja auch an Stelle von @ScriptDir setzen können, oder? Oder gibts da noch einen anderen Weg als mein "Versuch" im Skrippt das er sich das aus dem GUI merkt ?

    • Offizieller Beitrag

    Hier eine Variante mit Dateiauswahl:

    Spoiler anzeigen
    [autoit]


    $sFilename = FileOpenDialog('Bitte Textdatei zum konvertieren auswählen', @ScriptDir, 'Text (*.txt)', 1) ; Dialogbox zum auswählen der Datei
    If @error Then Exit ; wenn der Benutzer auf 'abbrechen' geklickt hat, dann Script beenden
    $sText = FileRead($sFilename) ; Datei einlesen
    $sText = StringReplace($sText, '-', '+ ') ; 1. Schritt: alle Minuszeichen in Pluszeichen mit zusätzlichem Leerzeichen
    $sText = StringRegExpReplace($sText, '(\+ ).(.).(.)', '$1$2$3') ; 2. Schritt: die Formatierung im ersten Block ändern
    $sText = StringRegExpReplace($sText, '(\+ .{6}).(.+)', '$1$2') ; 3. Schritt: die Formatierung im zweiten Block ändern
    $sNewFilename = StringRegExpReplace($sFilename, '(.+)(\.txt)', '$1_neu$2') ; Neuen Dateinamen generieren
    $hFile = FileOpen($sNewFilename, 2) ; Datei zum schreiben öffnen
    If $hFile <> -1 Then ; wenn erfolgreich, dann...
    FileWrite($hFile, $sText) ; neuen Text schreiben
    FileClose($hFile) ; Datei schließen
    EndIf

    [/autoit]
  • Oscar :
    Hab selber auch schon wieder Stunden dran gesessen und hatte es fast durch. Nur das er´s dann in das selbe Verzeichniss speichert mit anderem Namen, daran hab ich noch gesessen .... Allerdings war mein Skript (unendlich) viel länger. Habe dann demütig deine Zeilen in mein GUI eingefügt.
    Wenn du mir jetzt noch sagen könntest, wie ich die neue Dateiendung anders bennennen kann, geh ich auf die Knie.
    Die neuen Daten sollen nach dem umsetzen *.neu heißen (die alten heißen alle *.alt, was ja kein Thema ist).
    Habe mich schon an dem (\.txt) in deiner 7. Zeile versucht, da ich vermute das es da eingestellt werden kann; habe es aber noch nicht geschafft.

    • Offizieller Beitrag

    Als Dateiendung soll dann ".neu" da stehen?
    Dann geht es so:

    Spoiler anzeigen
    [autoit]


    $sFilename = FileOpenDialog('Bitte Textdatei zum konvertieren auswählen', @ScriptDir, 'Text (*.alt)', 1) ; Dialogbox zum auswählen der Datei
    If @error Then Exit ; wenn der Benutzer auf 'abbrechen' geklickt hat, dann Script beenden
    $sText = FileRead($sFilename) ; Datei einlesen
    $sText = StringReplace($sText, '-', '+ ') ; 1. Schritt: alle Minuszeichen in Pluszeichen mit zusätzlichem Leerzeichen
    $sText = StringRegExpReplace($sText, '(\+ ).(.).(.)', '$1$2$3') ; 2. Schritt: die Formatierung im ersten Block ändern
    $sText = StringRegExpReplace($sText, '(\+ .{6}).(.+)', '$1$2') ; 3. Schritt: die Formatierung im zweiten Block ändern
    $sNewFilename = StringRegExpReplace($sFilename, '(.+)\.alt', '$1.neu') ; Neuen Dateinamen generieren
    $hFile = FileOpen($sNewFilename, 2) ; Datei zum schreiben öffnen
    If $hFile <> -1 Then ; wenn erfolgreich, dann...
    FileWrite($hFile, $sText) ; neuen Text schreiben
    FileClose($hFile) ; Datei schließen
    EndIf

    [/autoit]
  • Hammer. :thumbup: Die $2 wars ... . Da hab ich noch gut was zu lernen.
    Dann kann ich das morgen hoffentlich zu einem guten Ende bringen. Kann mich nur noch einmal für die super kompetente und sehr schnelle Hilfe hier bedanken! Spitze! :thumbup:

  • Ich krieg die Kriese, bei deinen Zeilen 5 (die Variablen) und 6 steig ich leider aus. ;(
    Da hab ich Stunden verbracht, um das nachvollziehen zu können.
    http://www.autoit.de/dokumentation_…tringRegExp.htm
    Leider waren meine Beispieldaten ja etwas verkürzt um es zu vereinfachen, was sich jetzt als Schuss in den Ofen herausstellt.
    Ich dachte, das bissel umstellen bekommich dann hin; leider Fehlanzeige. Auch nimmst du (so wie ich es verstanden habe) das "d" von vorne weg, nicht das blaue von hinten (vgl. Startpost), was mich jetzt so heftig beschäftigt (Zeile 5 erster Teil). Der zweite Teil der Zeile (die $) erschließen mir nicht so richtig; da werden glaub ich die restlichen Inhalte via Variable überführt, aber gleichzeitig scheint $1 für das Schreiben der neuen Datei sehr wichtig zu sein (da er bei meine Versuchen sonst eher die alte Datei überschreibt und nicht eine neue anlegt).
    Ich kann ja mal den ganzen Dateiaufbau des wesentlichen bereiches von Quell und Zieldatei hinterlassen, wenn meine Vermutung stimmt, kann ja alles weitere eh via Variable übernommen werden. An N und R bin ich den ganzen Tag am verzweifeln ...:

    alt:
    xyabcdeeff900123 klmN717.968 opqR453.375 123.456

    neu:
    ________NR900123 klmN717.968 opqR453.375 123.456 (vorneweg 8 Leerzeichen)

    Könntest du bitte den Ausdruck dafür noch einmal hinterlassen ? Reguläre Ausdrück machen betroffen ... ;(

    • Offizieller Beitrag

    Bei den regulären Ausdrücken ist es sehr wichtig, wie die Formatierung aussieht und wie sie anschließend aussehen soll. Deswegen bei solchen Anfragen immer ganz genau schreiben was wie geändert werden soll und was dort möglicherweise für Zeichen stehen können.
    Für einen Anfänger sind solche reguären Ausdrücke nicht ganz einfach nachzuvollziehen (eigene Erfahrung), aber das kommt mit der Zeit.
    Hier jetzt also das geänderte Script:

    [autoit]


    $sFilename = FileOpenDialog('Bitte Textdatei zum konvertieren auswählen', @ScriptDir, 'Text (*.alt)', 1) ; Dialogbox zum auswählen der Datei
    If @error Then Exit ; wenn der Benutzer auf 'abbrechen' geklickt hat, dann Script beenden
    $sText = FileRead($sFilename) ; Datei einlesen
    $sText = StringRegExpReplace($sText, '.{10}(\d{6}) (.{3})(.)(.+?) (.{3})(.)(.+?) (.+?)', ' $3$6$1 $2$3$4 $5$6$7 $8') ; die Formatierung ändern
    $sNewFilename = StringRegExpReplace($sFilename, '(.+)\.alt', '$1.neu') ; Neuen Dateinamen generieren
    $hFile = FileOpen($sNewFilename, 2) ; Datei zum schreiben öffnen
    If $hFile <> -1 Then ; wenn erfolgreich, dann...
    FileWrite($hFile, $sText) ; neuen Text schreiben
    FileClose($hFile) ; Datei schließen
    EndIf

    [/autoit]


    Ich hoffe, dass das jetzt so passt, ansonsten melde Dich einfach nochmal. :)

  • Danke für deinen Hinweis bzgl. der Formatierung. Ich wollte es vereinfachen und dann halt (Lerneffekt) selber umstellen, aber die elegante Art, mit der du den regulären Ausdruck formuliert hattest, war für mich noch zu hoch. Auch die jetzige replace-Zeile ist (für mich) nicht ohne ;). Werde mich übers Wochenende mit ihr auseinandersetzen. Der Anfang ist ja kein Thema, aber dann ..... :) ... Ich hoff ich kriegs irgendwann nachvollzugen.
    Das Skript läuft bestens. Habe es ins GUI gesteckt, wo ich mir mehrere "Schalter" bastle für derartiges. Wenn man so langsam einsteigt, entdeckt man Stück für Stück wie nützlich dergleichen doch ist ... . Das macht Lust auf mehr :).
    Ich kann mich nur noch einmal ganz herzlich bedanken. :thumbup:

    • Offizieller Beitrag

    Ich habe Dir die Zeile mal kommentiert (vielleicht hilft das beim verstehen):

    [autoit]


    $sText = StringRegExpReplace($sText, '.{10}(\d{6}) (.{3})(.)(.+?) (.{3})(.)(.+?) (.+?)', ' $3$6$1 $2$3$4 $5$6$7 $8') ; die Formatierung ändern

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

    ; das Pattern gruppiert den String (pro Zeile)
    ; ".{10}" = 10 beliebige Zeichen, ohne Klammer, weil nicht benötigt
    ; "(\d{6})" = 6 Ziffern -> $1 in dem Ersetzungsstring
    ; "(.3)" = 3 beliebige Zeichen -> $2 in dem Ersetzungsstring
    ; "(.)" = 1 beliebiges Zeichen -> $3 in dem Ersetzungsstring
    ; "(.+?)" = 1 oder mehr beliebige Zeichen bis zum nächsten (wegen dem ?) Leerzeichen -> $4 in dem Ersetzungsstring
    ; "(.{3})" = 3 beliebige Zeichen -> $5 in dem Ersetzungsstring
    ; "(.)" = 1 beliebiges Zeichen -> $6 in dem Ersetzungsstring
    ; "(.+?)" = 1 oder mehr beliebige Zeichen bis zum nächsten (wegen dem ?) Leerzeichen -> $7 in dem Ersetzungsstring
    ; "(.+?)" = 1 oder mehr beliebige Zeichen bis zum nächsten (wegen dem ?) Leerzeichen -> $8 in dem Ersetzungsstring

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

    ; Im Ersetzungsstring kann man dann die Gruppen beliebig zusammensetzen, hier mit entsprechenden Leerzeichen dazwischen

    [/autoit]
  • Lieb von Dir, da bleiben keine Fragen offen. Ich mache mich jetzt schonan weitere Umsetzungen, Umrechnungen usw. . Es wird ... :D
    Vielen Dank, und falls ihr hier gern die Themen schließen solltet, kann das hier gern zu. Das Problem ist mehr als gelöst und Oscar bekommt ein ganz dicken :thumbup: !

  • Och Menno, was stimmt denn hier nicht ? Finde nach Stundenlanger Suche meinen Fehler nicht.
    Gleiche Problematik wie oben, "einfache" Umstellungen, Formate etwas anderes ...
    alt:
    ________ab200101 cde fghi917.422 jklm978.485 11.905 0.001 " "
    ________abcdefgh ijk lmnopqr.stu vwxyz12.345 678.900 0.002 "Moritz 0,1 10,5"

    soll zu
    neu:
    ________im200101 cde 3fghi917.422 jklm978.485 11.905 0.001 " "
    ________oycdefgh ijk 3lmnopqr.stu vwxyz12.345 678.900 0.002 "Moritz 0,1 10,5"

    Ähnlich dem ersten Beispiel, die Werte bei Spalte "i" und "m" nach vorne kopieren und vor "j" eine "3" ergänzen.
    Das Skript drum herum ist ja im Grunde genommen das selbe, nur die replace Zeile ist natürlich etwas anderes. Aber irgend einen Fehler habe ich in der replace Zeile und ich finde ihn nicht ...

    Spoiler anzeigen
    [autoit]


    $sFilename = FileOpenDialog('Bitte Textdatei zum konvertieren auswählen', @ScriptDir, 'Text (*.*)', 1) ;
    If @error Then Exit ;
    $sText = FileRead($sFilename) ;
    $sText = StringRegExpReplace($sText, '.{10}({6}) (.{3}) (.{3})(.)(.+?) (.{3})(.)(.+?) (.+?) (.+?)', ' $4$7$1 $2 3$3$4$5 $6$7$8 $9 $10 ') ; wo sitzt hier der Fehler ???
    $sNewFilename = StringRegExpReplace($sFilename, '(.+)\.*', '$1_m3.cst') ;
    $hFile = FileOpen($sNewFilename, 2) ;
    If $hFile <> -1 Then ;
    FileWrite($hFile, $sText) ;
    FileClose($hFile) ;
    EndIf

    [/autoit]


    Sieht jemand meinen Fehler und kannn mir einen Wink geben? So legt er die Datei zwar neu an, aber mit alt = neu ... ;(

    3 Mal editiert, zuletzt von sanni74 (5. März 2013 um 13:37)

    • Offizieller Beitrag

    Da fehlte ein Punkt und $10 gibt es nicht. Das geht nur von $1...$9.
    Aber so geht es:

    Spoiler anzeigen
    [autoit]


    $sFilename = FileOpenDialog('Bitte Textdatei zum konvertieren auswählen', @ScriptDir, 'Text (*.*)', 1)
    If @error Then Exit ;
    $sText = FileRead($sFilename) ;
    $sText = StringRegExpReplace($sText, '.{10}(.{6}) (.{3}) (.{3})(.)(.+?) (.{3})(.)(.+?) (".*")', ' $4$7$1 $2 3$3$4$5 $6$7$8 $9 ')
    $sNewFilename = StringRegExpReplace($sFilename, '(.+)\.*', '$1_m3.cst') ;
    $hFile = FileOpen($sNewFilename, 2) ;
    If $hFile <> -1 Then ;
    FileWrite($hFile, $sText) ;
    FileClose($hFile) ;
    EndIf

    [/autoit]

    P.S.: Zum einfügen von AutoIt-Code bitte den AutoIt-Tag im Editor benutzen und bei längeren Quelltexten zusätzlich den Spoiler verwenden.

  • Menno, hätte ich doch selber sehen müssen inzwischen grmpf ... X( /d raus genommen, wegen möglicher Buchstaben und keinen Punkt gesetzt.
    Deine Erklärungen hatte ich mir ausgedruckt und farblich hinterlegt, super.
    Ich werde mir wohl mal angewöhnen, meine Skripte auch auszudrucken. Auf dem Blatt wäre ich ev. über den fehlenden Punkt gestolpert.
    Danke. ^^
    Bzgl PS: Ich geb mir Mühe, habe es nacheditiert