Read file -> return Zeilennummer

  • Hallo zusammen,

    ein kurze Frage meinerseits. Ich kriege es nicht hin.

    Ich möchte die Datei nach einem Begriff durchsuchen und mir dann die Zeilennummer ausgeben lassen, um dann zu sagen, "suche ab der Zeilennummer weiter".

    mit _FileCountLines kann ich mir nur die komplette Anzahl ausgeben lassen..

    Ich möchte aber:

    AutoIt
    $Wert
    $Datei
    
    
    Suche $Wert in $Datei und gib die Zeilennummer (nicht den Inhalt) zurück....

    Geht das ?

    VG

    horphi

  • So würde ich es wohl machen:


    LG,
    der Robert

  • Probier es doch mal mit:

    AutoIt
    FileReadLine($sPath, $iLine)

    oder soetwas hier:

    EDIT: für größere Dateien hab ich es mal angepasst mit FIleOpn und FileClose!

  • @DasIch Außerdem ist mir in deinem Skript ein Fehler aufgefallen... du überprüfst durch Ubound() - 1 nie das letzte Element deines Arrays etweder du nimmst nur Ubound oder das hier:

    Denn in $aDatei[0] befindet sich schon der Wert den Ubound($aDatei) zurückgeben würde

  • Das letzte Element wird in meinem Beispiel auch geprüft. Der Code ist voll funktionial. Allerdings wird die schleife nicht abgebrochen, wenn der Eintrag gefunden wurde. Daher hier nochmal angepasst:

    Ubound - 1 daher, dass das 0. Element im Array den Count des Arrays angibt und daher übersprungen wird. Du hast da wohl einen Denkfehler ;)

  • Und wieder bist du zu müde :D

    Ich habe sie im ersten Post nicht abbrechen lassen, um aber das Skript schneller laufen lassen zu können habe ich im zweiten Post die Schleife abbrechen lassen :P

  • Meine Lösung:

    AutoIt
    $sFile = FileOpenDialog("Datei ?", @ScriptDir, "Alle (*.*)")
    $sSearch = InputBox("Suchstring ?","Geben Sie den zu suchenden Text ein:")
    
    
    $FileData = FileRead($sFile)
    $sFound = StringLeft($FileData, StringInStr($FileData, $sSearch))
    $sOut = StringReplace($sFound, @LF, "")
    
    
    Msgbox(0,"",@extended + 1)

    Edit: Zeilentrenner in @LF geändert. Ist dann auch Linux kompatibel.

    Zur Nutzung dieses Forum's, ist ein Übersetzer für folgende Begriffe unerlässlich:

    "On-Bort, weier, verscheiden, schädliges, Butten steyling, näckstet, Parr, Porblem, scripe, Kompletenz, harken, manuel zu extramieren, geckukt, würglich, excell, acces oder Compilevorgeng"

    2 Mal editiert, zuletzt von Micha_he (25. September 2015 um 09:14)

  • Hey ho, das klappt ja super. :)

    Vielen DAnk. :)

    Nur ich verstehe die Vorgehensweise mit @extended nicht....

    Spoiler anzeigen

    EIne Frage hab ich noch:

    Kann ich auch festlegen, ab welcher Zeile gesucht werden soll?

    VG

    horphi

  • Also, Micha hat die mit Abstand effektivste Lösung gefunden. :D

    Woher das @extended kommt, ist auch leicht zu beantworten. StringReplace ersetzt ja einen bestimmten Suchstring in einem Arbeitsstring durch einen Ersatzstring. Damit man danach noch nachvollziehen kann, wie viele Ersetzungen eigentlich durchgeführt worden sind, belegt StringReplace das @extended-Macro mit der Anzahl der Ersetzungen. Generell enthält dieses Makro immer gewisse Zusatzinformationen über den letzten Funktionsaufruf, die im Normalfall vernachlässigt werden können.
    Micha wendet dann hier einen kleinen Trick an: Er ersetzt alle Zeilenumbrüche (@LF) durch einen Leerstring und verwirft dann schließlich das Ergebnis. Nun kann er aber über @extended nachschauen, wie viele @LFs überhaupt ersetzt worden sind. Und wenn man weiß, dass z.B. 4 @LFs ersetzt worden sind, so kann ich mir daraus zusammenreimen, dass insgesamt 5 Zeilen vorhanden gewesen sein müssen. 5, weil nach der letzten Zeile ja kein Zeilenumbruch mehr steht.

    Das ist natürlich wesentlich effektiver und effizienter, als die Datei Zeile für Zeile durchzugehen.

  • EIne Frage hab ich noch:

    Kann ich auch festlegen, ab welcher Zeile gesucht werden soll?

    Klar, mit etwas mehr Aufwand:

    AutoIt
    $sFile = FileOpenDialog("Datei ?", @ScriptDir, "Alle (*.*)")
    $sSearch = InputBox("Suchstring ?","Geben Sie den zu suchenden Text ein:")
    $iFromLine = InputBox("Ab Zeile ?","Geben Sie die Startzeile ein:", 1)
    $FileData = FileRead($sFile)
    $iStartPos = StringInStr($FileData, @LF, 0, $iFromLine - 1) + 1
    $sFound = StringLeft($FileData, StringInStr($FileData, $sSearch, 0, 1, $iStartPos))
    $sOut = StringReplace($sFound, @LF, "")
    Msgbox(0,"Ausgabe", "Gefunden in Zeile: " & @extended + 1)

    Zur Nutzung dieses Forum's, ist ein Übersetzer für folgende Begriffe unerlässlich:

    "On-Bort, weier, verscheiden, schädliges, Butten steyling, näckstet, Parr, Porblem, scripe, Kompletenz, harken, manuel zu extramieren, geckukt, würglich, excell, acces oder Compilevorgeng"

  • Tach zusammen,

    Habe die Suche endlich mal ausgebaut.

    Problem dabei: ich lasse mir jede Zeile vom Suchanfang bis zum SuchEnde einzeln ausgeben....das ist ein bisschen langsam.

    Kennt jemand einen Weg, das zu beschleunigen?

    Danke und Gruß,

    horphi

    Spoiler anzeigen
    • Offizieller Beitrag

    Das ist immer wieder der gleiche Fehler!
    FileReadLine niemals mehrfach mit dem Dateinamen aufrufen. Das dauert ewig, weil intern die Datei geöffnet wird, es wird bis zu der Zeile "eingelesen" und dann wird erst die gesuchte Zeile zurückgegeben.
    Wenn Du das mehrfach brauchst, dann immer mit dem Dateihandle arbeiten, also die Datei mit FileOpen öffnen und dann FileReadLine mit dem Dateihandle (Rückgabe von FileOpen) benutzen.
    Am Ende nicht vergessen die Datei mit FileClose wieder zu schliessen, ansonsten liegt ein Lock auf der Datei.

    Wenn Du sowieso jede Zeile durchgehst, brauchst Du dann auch $extend nicht, weil jedes folgende FileReadLine immer die jeweils nächste Zeile einliest.

  • Hallo Oscar,

    ich rufe die Datei über FileOpenDialog auf und übergebe sie in FileRead.

    Kann ich aus FileRead in FileReadLine übergeben und mit einer For/Next Schleife die Daten aus dem @extended Container (also die Zeilennummer) nutzen?


    VG

    horphi

    • Offizieller Beitrag

    Hier ein kurzes Bsp., wie man mit Dateihandle arbeitet:

  • Kann ich aus FileRead in FileReadLine übergeben und mit einer For/Next Schleife die Daten aus dem @extended Container (also die Zeilennummer) nutzen?

    Ich verstehe ehrlich gesagt nur Bahnhof.
    Ich glaube das ist ein typischer Fall von XY-Problem.
    Das bedeutet:

    • Ein User möchte X erreichen.
    • Er glaubt die Lösung des Problems wäre Y.
    • Da es dabei Probleme gibt stellt er eine Frage Y betreffend aber ohne X zu erwähnen.
    • Effektiver wäre für Ihn aber die Fragestellung: Ich möchte X erreichen dazu habe ich schon Y probiert aber noch immer nicht das gewünschte erreicht.

    Ich weiß ehrlich gesagt noch nicht was du warum erreichen möchtest.
    Sag uns mal den konkreten Anwendungsfall und dann finden wir sicherlich eine gute Lösung dafür.

    Sonst können wir nur raten.
    Hier daher mal mein Rateversuch: Alle Vorkommen eines Strings mit Angabe der Zeilennumer mit einem Zeilenoffset:

  • Hallo AspirinJunkie,

    danke für deine Rückmeldung.

    ENtschuldige, wenn ich mich nicht richtig ausgedrückt habe.

    1.Ich möchte wie im 1. Post beschrieben TXT Files durchsuchen und mir die Zeilennummer (nicht den Inhalt) des Ergebnis wiedergeben lassen.
    2. will ich dann von da weitersuchen bis zur nächsten Leerzeile. (also StringLen = 0)
    3. Der gefundene Bereich von Ergebnis bis nächster Leerzeile soll in eine GUI geschrieben werden, damit ich es weiterverarbeiten kann.

    Das habe ich hiermit auch hinbekommen, nur durchsucht die Schleife die Datei immer wieder von vorne, weil ich die Datei bei Jeder Schleife erneut einlesen....das ist bei 1000 Zeilen sehr viel...

    Spoiler anzeigen

    VG
    horphi