Benötige Infomaterial für Anfänger - Bearbeiten von Textdateien

  • Hallo,
    ich habe noch absolut keine Erfahrungen mit AutoIT, würde mich aber gern näher damit beschäftigen.
    Da das Tool recht umfangreich scheint, würde ich gern mit einem existierenden Problem bei mir beginnen und daran lernen.
    Ich habe eine Textdatei, es handelt sich um eine Konfigurationsdatei aus einem Mikrotik Routerboard, aus der ich einen bestimmten Teil benötige, wenn eine gewisse Bedingung erfüllt ist.

    Hier mal ein Beispiel von einem Inhalt, den wichtigen Teil habe ich mal farblich markiert:
    add configuration=xxxxxxx disabled=no mac-address=00:00:00:00:00:00 \
    master-interface=1.4-67370665861D-1 name=\
    1.4-67370665861D-1-9 radio-mac=00:00:00:00:00:00
    add configuration=xxxxxxx disabled=yes mac-address=00:00:00:00:00:00 \
    master-interface=1.4-67370665861D-1 name=\
    1.4-67370665861D-1-10 radio-mac=00:00:00:00:00:00
    add configuration=xxxxxxx disabled=no mac-address=00:00:00:00:00:00 \
    master-interface=1.4-67370665861D-1 name=\
    1.4-67370665861D-1-11 radio-mac=00:00:00:00:00:00

    Natürlich ist in der Datei vor dem ersten "add configuration" und danach noch anderer Text, der ignoriert werden kann.
    Ich müsste nun, immer wenn disable=no auftaucht den Wert der übernächsten Zeile in eine neue Textdatei bekommen und noch ein "enable " davorsetzen.
    Also wie hier in dem Beispiel eine neue Textdatei mit dem Inhalt:

    enable 1.4-67370665861D-1-9
    enable 1.4-67370665861D-1-11

    Vielleicht kann mir ja jemand behilflich sein, bevor ich noch weitere Stunden versuche das hin zu bekommen.
    Ich habe zwar schon einiges gelesen, aber ich bin noch nicht auf der richtigen Spur um das zu realisieren.

    THX

    MotD

    • Offizieller Beitrag

    Man kann da mit StringRegExp beigehen. Dafür ist es aber ganz elementar wichtig, wie so eine Datei tatsächlich aufgebaut ist.
    Besser wäre es, wenn Du die Datei mal als Anhang posten würdest, damit man die Zeilenenden korrekt sieht.
    Ich habe mal Deine "\" oben als @CRLF gedeutet und darauf basierend ein Beispiel geschrieben:

  • Hi,
    die gesamte Konfigurationsdatei möchte ich aufgrund der Passworte, SSIDs usw. eher nicht posten.
    Aber ich denke, du hast recht es sind Zeilenumbrüche + LineFeed (CRLF) in der Konfigurationsdatei.

    Ich habe mir dein Script auch gerade mal angeschaut, es ausprobiert und versuche es gerade zu verstehen.
    So im groben komme ich auch dahinter, nur müsste ich ja eine Datei frei wählen können und unter einem anderen Namen das Ergebnis abspeichern.
    In deinem Schipt hast du den gesamten Text ja in einer Variable, den er sich eigentlich komplett selbst suchen sollte.

    THX
    MotD

  • Hallo @MotDy2k,

    mein erster Beitrag hier lautete in etwa so: "Hallo Leute, ich habe keine Ahnung von AutoIt, möchte aber alles Mögliche zum Bearbeiten von Texten lernen. Könnt ihr mir zeigen, wie ich etwa das mache..". Daher hege Sympathie für dein Anliegen :D

    Hier gibt es viele Methoden. Den schnellsten und elegantesten hat dir Oscar mit StringRegExp gezeigt. Wenn du gleich damit loslegst, wirst du bald sehr weit kommen. Für einen Anfänger ist es aber doch schwer, dass auf andere Beispiele zu übertragen. Daher habe ich mir mal Mühe gegeben um dir ein paar Funktionen zu zeigen, mit denen du einiges mit Texten machen kannst.

    Das Skript ist nicht der einfachste Weg und selbst für diesen Weg sind da einige unnötige Zeilen. Man könnte etwa direkt in der ersten Schleife mit dem FileWrite anfangen, aber ich wollte noch ein paar Zuweisungsmethoden zeigen.

    ACHTUNG: Lege vor der Ausführung des Codes im gleichen Verzeichnis eine Textdatei mit Namen "Logfile.txt" ab, in der, der von dir im ersten Beitrag gezeigte, Text steht. (Der Text ist hier nicht schon integriert wie bei Oscar, sondern er soll aus einer Datei eingelesen werden).

    Spoiler anzeigen


    So und hier habe ich das Skript noch einmal ganz ausführlich (und hoffentlich in der Hauptsache korrekt) erklärt, damit du einen möglichst guten Einstieg in einige Funktionen findest, die dir hierbei ständig über den Weg laufen könnten.

    Spoiler anzeigen

    Viel Erfolg.

    Grüße autoiter

    Einmal editiert, zuletzt von autoiter (14. Juni 2017 um 06:38) aus folgendem Grund: Die Ausführung zu StringInStr noch um Zwischenspeichern ergänzt.

  • _Example

    PS: AutoIt ist kein "Tool", sondern eine Scriptsprache. :D

    @autoiter
    Mach das noch 27 mal und wir sind keine Freunde mehr... :P

  • Hey vielen Dank @De Rand Ere,
    es gibt sie. Schau mal hier: Listview-Datenbank v3
    Gerade von Oscar habe ich noch andere so extrem ausführlich kommentierte Skripte gesehen (leider gerade nicht gefunden).


    @autoiter
    Mach das noch 27 mal und wir sind keine Freunde mehr...

    Hehe, gerade habe ich erst deine Drohung bemerkt, @Bitnugger ,
    Da muss man einfach drüber stehen. Der alpines hat gefühlt schon hundert mal die Antwort weggeschnappt. ^^
    Außerdem bist du vielleicht einmal nicht schneller, aber hast ja meist die bessere Antwort als ich ;)

    Grüße autoiter

    2 Mal editiert, zuletzt von autoiter (14. Juni 2017 um 06:48)

  • @autoiter

    Vielen Dank für deine Mühe / Hilfe und die absolut grandiosen Erklärungen!
    Und natürlich hast du Recht, mein erster Beitrag klang wohl wirklich so *g*
    Ich wollte eigentlich zum Ausdruck bringen, das ich mit AutoIT noch keine Erfahrungen habe, mich das Teil aber schon länger reizt.
    Ganz Fremd bin ich in Scriptsprachen nicht, daher dachte ich ich könnte die Anforderung mal in AutoIT versuchen und dabei den Umgang damit lernen.

    @Bitnugger
    Mir war schon klar, was es ist ;) Aber danke für den HInweis, künftig nenne ich es dann anders *g*

  • Ergänzung zu dem was @autoiter in den Kommentaren zu seinen Example geschrieben hat...

    Local $hFileOpen = FileOpen(@ScriptDir & "\Ergebnis.txt", $FO_OVERWRITE) ; Schreibst du häufiger in eine Datei, ist es sinnvoll,
    ; die Datei mit der Funktion FileOpen zu öffnen/erstellen und mit dem handle weiter zu arbeiten.

    Zusätzlich hat es den Vorteil, dass man die Codepage angeben kann, in der die Daten gespeichert werden... Default (ohne FileOpen) ist UTF8 (without BOM)

    Wenn du also Textdateien speichern willst, die im Normalfall unter Windows mit der Codepage 1252 (ANSI) angelegt werden, ist ein FileOpen auf jeden Fall eine gute Idee.

    Local $hFileOpen = FileOpen($sFilePath, BitOR(FO_READ, $FO_ANSI)) ; einzulesende Datei wurde mit der Codepage 1252 (ANSI) gespeichert und soll auch mit dieser geöffnet werden...
    Local $hFileOpen = FileOpen($sFilePath, BitOR(FO_OVERWRITE, $FO_ANSI)) ; die Datei soll mit der Codepage UTF-8 ohne BOM (65001) gespeichert werden...
    Local $hFileOpen = FileOpen($sFilePath, BitOR(FO_READ, $FO_BINARY)) ; die Datei soll als Binärdatei (z. B. *.dll, *.exe) eingelesen werden...

  • Moin,

    dank eurer Hilfe bin ich extrem weiter gekommen, habe auch etliches gelesen vor allem zur Bearbeitung von Textdateien wie auch Variablen usw. und den Konstanten auf Anraten von autoiter nicht die Flags bei z.B. einer MessageBox zu nutzen usw.

    Hier mal ein Auszug aus meinem Script, die Möglichkeit die Verarbeitung der gewählen Datei mit OK zu starten oder Abzubrechen:

    AutoIt
    if MsgBox($MB_ICONINFORMATION + $MB_OKCANCEL,"Hinweis","Folgende Datei ausgewählt: "& @CRLF & $fileToUse) = 1 thenElse    Exit


    Ich habe es natürlich getestet und es funktioniert, aber ich würde gerne wissen ob es die richtige / eine gute / sinnvolle Vorgehensweise ist.
    Mir ist schon klar, das es in dieser Scrpitsprache viele Möglichkeiten gibt, ans Ziel zu kommen daher gibt es sicher auch andere Lösungen.
    Nur weil etwas funktioniert bedeuet es ja nicht, das es gut / richtig ist ;). Und ich lerne ja noch lange *g*

    Zudem habe ich noch eine Frage, zu der ich noch keine wirkliche Lösung gefunden habe und an die ich vorher nicht gedacht habe.
    In dem Konfigurationsfile vom MikroTik ist es so, das bei einigen Interfaces der gesuchte Wert nicht unbedingt zwei Zeilen darunter steht - gerade bei Physikalischen Interfaces.

    Gibt es die Möglichkeit, im Script zu bestimmen suche das erste "add configuration=" und gib mir den Teil der nach dem darauffolgenden "name=" kommt, gleich wo er auftaucht und wie lang der Text ist bis zum Leerzeichen.
    Also gleich ob in der Zeile oder ein, zwei, drei Zeilen später aber vor dem nächsten "add configuration="?
    Klar gibt es die Möglichkeit sicherlich, ich weiß halt nur nicht wie *g*

    Hier noch Mal meine Beispielkonfiguration mit der neuen Zeile, die ich absichtlich mal in der Mitte eingefügt habe:
    add configuration=xxxxxxx disabled=no mac-address=00:00:00:00:00:00 \
    master-interface=1.4-67370665861D-1 name=\
    1.4-67370665861D-1-9 radio-mac=00:00:00:00:00:00
    add configuration=xxxxxxx disabled=no l2mtu=1600 mac-address=\
    00:00:00:00:00:00 master-interface=none name=7-673706ADC0EA-1 \
    radio-mac=00:00:00:00:00:00
    add configuration=xxxxxxx disabled=yes mac-address=00:00:00:00:00:00 \
    master-interface=1.4-67370665861D-1 name=\
    1.4-67370665861D-1-10 radio-mac=00:00:00:00:00:00
    add configuration=xxxxxxx disabled=no mac-address=00:00:00:00:00:00 \
    master-interface=1.4-67370665861D-1 name=\
    1.4-67370665861D-1-11 radio-mac=00:00:00:00:00:00

    Ich habe zwar schon vieles ausprobiert und getestet aber entweder stehe ich auf dem Schlauch oder habe den richtigen Weg noch nicht gefunden.
    Habe auch schon versucht alle CRLF zu entfernen und nur vor jedem "add configuration=" einzufügen, damit ich den Teil aus dem Konfigfile der für mich interessant ist Zeilenweise habe.
    Hat auch alles wunderbar funktionert, ich dachte es wäre einfacher dann den Text Zeilenweise nach "add configuration=" und dem "name=" durchsuchen zu lassen.
    Also die Zeile als Grenze der Suche, nach dem Motto suche nur in der Zeile nach "name=" in der du auch das "add configuration=" hast und gib mir den Wert.

    Irgendwie habe ich mich aber wohl falsch ausgedrückt und das Ergebnis war eher dürftig *g*

    Könnte mir hier bitte noch Mal jemand auf die Sprünge helfen?

    Dank Euch!

    THX
    MotD

    Einmal editiert, zuletzt von MotDy2k (17. Juni 2017 um 08:44)

  • Hi,

    hier mal eine Beispielkonfiguration, die Werte wie Passworte usw. habe ich geändert aber das Dateiformat / der Aufbau ist unverändert.
    Eigentlich ist die Dateiendung .rsc, aber ich musste sie umbenennen da die Dateiendung abgeleht wurde.

    Es geht um den Bereich ab "/caps-man interface", in diesem Fall bis "/ip pool" - allerdings könnte bei erweiterter Konfiguration ein anderer Abschnitt anstatt "/ip pool" folgen.


    Im Prinzip benötige ich für jede Zeite von den "add configuration=" Zeilen, bei denen "disabled=no" ist, den Wert der hinter "name=" auftaucht, egal ob in der gleichen der 2. oder 3 o.ä. Zeile danach.

    Der Text hinter "name=" kann natürlich unterschiedlich lang sein, daher halt bis zum nächsten Leerzeichen.


    THX

    • Offizieller Beitrag

    Das würde dann mit StringRegExp so aussehen:

  • Vielen Dank für die Hilfe, soweit für mich auch alles verständlich und nachvollziehbar.
    Nur die eine Zeile nicht ganz, könntest du mir die etwas erklären:

    AutoIt
    $aOut = StringRegExp($sText, '(?s)disabled=no.+?name=\\*\s*(.+?)\s+', 3)

    Die Funktionsbeschreibung habe ich mir schon angeschaut und der Aufbau der Funktion ist mir auch verständlich.
    Bis zu dem Teil "name=\\" komme ich auch noch mit, aber der Rest ist mir noch nicht ganz klar. Zumal am Ende das ", 3)" das Flag sein soll und in eckige Klammern gehört?
    Oder irre ich mich da total? Das \s oder ?s ist mir auch klar, aber \\* z.B. nicht.

  • Bis zu dem Teil "name=\\" komme ich auch noch mit, aber der Rest ist mir noch nicht ganz klar. Zumal am Ende das ", 3)" das Flag sein soll und in eckige Klammern gehört?

    \\* 0 or more, greedy. Matcht also 0 oder so viele nachfolgende Backslashes wie nur irgendwie möglich.
    \s* Dasselbe wie vorhin nur mit Whitespaces.
    (.+?)\s+ Matcht alle Strings die darauffolgend ein oder mehrer Whitespaces haben.

    Der Flag 3 gibt dir an, dass der Returntype der Funktion ein Array sein soll. Alle Funde werden dir in ein Array gepackt und zurückgegeben.

  • Danke, damit komme ich schon deutlich weiter!

    Sicher eine ganz blöde Frage, aber warum wird das Flag nicht wie in der Funktionserklärung in den eckigen Klammern angegeben?
    Wie hier im Beispiel der Erklärung
    StringRegExp ( "test", "pattern" [, flag = 0 [, offset = 1]] )

  • Sicher eine ganz blöde Frage, aber warum wird das Flag nicht wie in der Funktionserklärung in den eckigen Klammern angegeben?

    Es ist eine Konvention, dass optionale Parameter in der Dokumentation in eckigen Klammern angegeben werden.
    Du kannst diese Parameter setzen, musst sie aber nicht setzen. Die Funktion arbeitet dann mit den Standardparametern.

    Wenn du, sagen wir mal, den Parameter offset setzen möchtest aber den Flag-Parameter nicht verändern willst, und aus dem Kopf nicht weißt welcher Wert der Standardwert ist, so nimmst du einfach den Wert der in den optionalen Parametern dahinter steht. In diesem Falle 0.

  • So, nun bin ich eigentlich fast fertig.
    Mit Sicherheit hätte man das ein oder andere einfacher, besser machen können - für Tipps bin ich Dankbar :).
    Zudem habe noch ein paar Fragen, zu denen ich keine Lösung / Antwort gefunden habe.

    1. Ich habe die Schriftart Verdana verwendet, offensichtlich wird sie nicht im Script eingebettet.
    Und obwohl die Schriftart auf einem anderen PC vorhanden ist, wird sie falsch angezeigt (zu groß usw.)
    Wie bekomme ich es hin, das die Schriftart immer gleich ist, evtl. auch wenn diese auf dem PC nicht installiert ist?

    2. Ich wollte eigentlich gerne ein GUI für die Abfrage nach dem Zieldateinamen, vor allem weil bei der Inputbox OK und Cancel auftaucht (das Cancel stört mich)
    Nur habe ich es nicht geschafft das GUI zu verlassen, also einen neuen Dateinamen mit zu übernehmen und somit das GUI und die Until Funktion zu verlassen.

    Aber hier erstmal das vorerst fertige Script

  • Und obwohl die Schriftart auf einem anderen PC vorhanden ist, wird sie falsch angezeigt (zu groß usw.)
    Wie bekomme ich es hin, das die Schriftart immer gleich ist, evtl. auch wenn diese auf dem PC nicht installiert ist?

    Wird die Standard-Schriftart vetrwendet oder ist einfach die Größe anders? Wenn die Größe anders ist, dann solltest du mal schauen ob an dem Rechner eventuell die DPI-Einstellung anders ist.

    Nur habe ich es nicht geschafft das GUI zu verlassen, also einen neuen Dateinamen mit zu übernehmen und somit das GUI und die Until Funktion zu verlassen.

    Kannst du das vielleicht anders formulieren? Ich steig da nicht ganz durch.

  • Hi,

    Bezüglich der Schriftart, könnte sein das die DPI-Einstellung anders ist das müsste ich noch Mal prüfen.
    Gibt es dafür denn eine Lösung? So ist es ja nun so das der Text nicht mehr in die definierten Feld / Button größen passt und abgeschnitten wird.
    Zudem kann das ja auf jedem PC anders sein.

    Ich habe versucht in der DO Until Anweisung die Inputbox durch ein GUI zu ersetzen, soweit auch kein Problem.
    Aber mit einem Klick auf OK oder Enter komme ich nicht aus der GUI, ein ExitLoop usw. hat hier nicht funktioniert.

    Hier mal einer der Versuche: