log-file auswerten

  • Hi@ all

    Hab da mal ne Frage:

    Habe mir ein Skript gebastelt, welches mir den LETZTEN Wert in einer Zeile in einem Log-File ausgibt.

    Spoiler anzeigen

    #include <Array.au3>


    $file = "log.log"

    $file = FileOpen($file, 0)


    Dim $avArray[1]

    While 1

    $line = FileReadLine($file)
    If @error = -1 Then ExitLoop

    $result =StringInStr($line,"EAN-Code:")
    If $result = 1 Then
    $ean = StringTrimLeft ( $line, 10 )

    _ArrayAdd( $avArray,$ean)

    EndIf


    WEnd

    FileClose($file)

    ;_ArrayDisplay( $avArray, "Updated Array" )

    $last=UBound($avArray)

    $last = $avArray[$last-1]

    MsgBox(0,"letzter Eintrag","der letzte eintrag war "&$last)

    log-FILE :

    Spoiler anzeigen

    ----------------------------------------
    [08-24-2009 - 11:02:03]:
    Version: Ver. 2.04
    EAN-Code: 4022709224101
    Variante: 19
    EEPROM Format: Ver. 09.00
    Quarzabweichung: 7.65[s/d] abgeglichen auf +0.00[s/d]
    Temperatur: 24.09[°C]

    ----------------------------------------

    [08-24-2009 - 11:03:03]:
    Version: Ver. 2.04
    EAN-Code: 4025709224101
    Variante: 20
    EEPROM Format: Ver. 09.00
    Quarzabweichung: 7.65[s/d] abgeglichen auf +0.00[s/d]
    Temperatur: 24.09[°C]

    ----------------------------------------

    ####

    so : Funktioniert super. . . ABER viel zu langsam !!

    die Files haben in der regel 2 MB ( Monatsweise )

    Die Ausgabe dauert rund 40 Sek.

    Hat jemand ne Idee, wie des schneller gehen kann ?

    Irgend wie File von hinten her lesen ?

    oder kurz vor Ende anfangen ? irgend wie sowas ..

    DANKE !

    Einmal editiert, zuletzt von vivus (21. September 2009 um 17:46)

  • Hallo vivus,

    diese Version sollte etwas schneller sein:

    Spoiler anzeigen
    [autoit]

    #include <array.au3>
    #Include <string.au3>

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

    Global $hFile, $Log, $aLog

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

    $hFile = FileOpen("log.log",0)
    $sLog = FileRead($hFile)
    FileClose($hFile)
    $aLog = _StringBetween($sLog,"EAN-Code: ","Variante: ")
    _ArrayDisplay($aLog)

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

    $last = UBound($aLog)

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

    $last = $aLog[$last - 1]

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

    MsgBox(0, "letzter Eintrag", "der letzte eintrag war " & $last)

    [/autoit]

    mfg (Auto)Bert

    • Offizieller Beitrag

    Du kannst direkt die letzte Zeile lesen:

    [autoit]

    #include< File.au3>
    $file = 'Dein_Pfad_zur_Log'
    $lines = _FileCountLines($file)
    MsgBox(0, 'Inhalt letzte Zeile', FileReadLine($file, $lines))

    [/autoit]

    Falls noch ein Zeilenumbruch zusätzlich enthalten ist, kann die letzte Zeile leer sein - dann halt: $lines-1
    So kannst du dann in einer Schleife rückwärts die letzten 7 Zeilen deines Log-Blocks auslesen.

  • Hallo AutoBert

    habe deine Version gerade getestet.

    gestoppte 2:36 Minuten .. bei 10253 Einträgen

    .. im Gegensatz zu 2:02 Minuten mit meiner Version..

    alternative ? muss unter 5 sec kommen ..

    aber trotzdem Danke !!

  • Hallo BusFix

    deine Version

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

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

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

    $file = "log.log"

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

    $lines = _FileCountLines($file)

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

    ;MsgBox(0,"lines",$lines)

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

    ;MsgBox(0, 'Inhalt letzte Zeile', FileReadLine($file, $lines))

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

    ;$file = FileOpen($file, 0)

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

    Dim $avArray[1]

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

    $lines=$lines-20

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

    While 1

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

    $line = FileReadLine($file,$lines)
    If @error = -1 Then ExitLoop

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

    $result =StringInStr($line,"EAN-Code:")
    If $result = 1 Then
    $ean = StringTrimLeft ( $line, 10 )

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

    _ArrayAdd( $avArray,$ean)

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

    EndIf

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

    $lines=$lines+1

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

    WEnd

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

    FileClose($file)

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

    ;_ArrayDisplay( $avArray, "Updated Array" )

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

    $last=UBound($avArray)

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

    $last = $avArray[$last-1]

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

    MsgBox(0,"letzter Eintrag","der letzte eintrag war "&$last)

    [/autoit]

    bringt beachtliche 38 SEC !!!

    ist ja schon "fast" GUT ! ;)

    32 SEC sollten noch weg .. noch ein Vorschlag ?

    Vielen Vielen DANK ! !

  • Hallo vivus,

    ich weis ja nicht mit welchen Prozessen dein Rechner sonst noch beschäftigt ist, hier meine Messungen für 10500 Einträge(NetBook Acer Aspire One, also wirklich nicht der schnellste) deine Version: 2392 ms, meine Version 823 ms, Version BugFix 105 ms,

    Hier nochmal die Version von Bugfix (Pfad etc, angepasst),

    [autoit]

    #include <File.au3>
    $begin = TimerInit()

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

    $file = 'log.log'
    $lines = _FileCountLines($file)
    $dif = TimerDiff($begin)

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

    MsgBox(0, 'Inhalt letzte Zeile', StringTrimLeft(FileReadLine($file, $lines-6), 10)) ; eventuell $lines-6 anpassen
    MsgBox(0,"Zeitunterschied",$dif)

    [/autoit]

    mfg (Auto)Bert

    mfg (Auto)Bert

    • Offizieller Beitrag

    Und das hier könnte noch etwas schneller sein (hab mal eine Testdatei mit 2,7 MB verwendet [100600 Zeilen], _FileCountLines($file) ist der Zeitfresser. Mit 1,5 GHz braucht es 2,5 sec. bei mir :

    Spoiler anzeigen
    [autoit]

    #include <File.au3>
    $start= TimerInit()
    $file = @ScriptDir & '\test_write.log'
    $lines = _FileCountLines($file)
    $lastLog = ''
    While 1
    If Not StringInStr(FileReadLine($file, $lines), 'Temperatur:') Then
    $lines -= 1
    ContinueLoop
    Else
    Do
    $zeile = FileReadLine($file, $lines)
    $lastLog = $zeile & @CRLF & $lastLog
    $lines -= 1
    Until StringLeft($zeile, 1) = '['
    ExitLoop
    EndIf
    WEnd

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

    ConsoleWrite($lastLog & @CRLF)
    ConsoleWrite('Zeit: ' & TimerDiff($start) & @CRLF)

    [/autoit]
  • Hallo AutoBert

    Mit deiner angepassten Version von Bugfix komme ich auf 829 ms.

    Wäre absolut top.

    Aber es ist ja nicht immer die 6.- letzte Zeile..

    Das Programm, welches das Log-file generiert, schreibt kontinuirlich in das File.

    deshalb auch der knappe zeit Rahmen von unter 5 sec, weil eine neue Messung um die 6 sec liegt.

    und bei einem bestimmten EAN-Code eine Meldung erscheinen soll.

    ich denke, dass dann der enorme Zeitverlust, an "meinem" suchverfahren liegt.

    dann werde ich jetzt mal versuchen , das zu umgehen.. . irgendwie

    ..warum mein Rechner soo viel langsamer ist wie deiner.. kann ich dir leider nicht sagen ..

    danke noch mal ...

  • Hi,
    meine Anpassung:

    Spoiler anzeigen
    [autoit]

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

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

    $logfile = "log.log"

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

    $lines = _FileCountLines($file)

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

    ;MsgBox(0,"lines",$lines)

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

    ;MsgBox(0, 'Inhalt letzte Zeile', FileReadLine($file, $lines))

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

    ;$file = FileOpen($file, 0)
    $lines=$lines-20
    Dim $avArray[$lines]
    $count = 1
    $file = FileOpen ($logfile, 0)
    While 1
    $line = FileReadLine($file,$lines)
    If @error = -1 Then ExitLoop

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

    If StringInStr($line,"EAN-Code:") = 1 Then
    $avArray [$count] = StringTrimLeft ( $line, 10 )
    $count += 1
    EndIf

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

    $lines=$lines+1

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

    WEnd

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

    FileClose($file)

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

    ;_ArrayDisplay( $avArray, "Updated Array" )

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

    MsgBox(0,"letzter Eintrag","der letzte eintrag war " & $avArray [$count - 1])

    [/autoit]

    ;-))
    Stefan

    • Offizieller Beitrag

    Du brauchst nur den letzten EAN? Das geht ganz fix mit RegEx:

    [autoit]

    #include <File.au3>
    $start= TimerInit()
    $file = @ScriptDir & '\test_write.txt'

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

    $ret = StringRegExp(FileRead($file), 'EAN-Code: \d+', 3)
    ConsoleWrite('letzter EAN-Code: ' & $ret[UBound($ret)-1] & @CRLF)

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

    ConsoleWrite('Zeit: ' & TimerDiff($start) & @CRLF)

    [/autoit]

    Edit:
    Und wenn du nur den numerischen Wert möchtest, dann so:

    [autoit]

    $ret = StringRegExp(FileRead($file), '(?:EAN-Code: )(\d+)', 3)

    [/autoit]
  • BugFix !! alle ACHTUNG !!

    Zeit: 233.57348757058

    klasse !! so funktioniert's !!

    könntest du mir aber bitte

    ==> $ret = StringRegExp(FileRead($file), '(?:EAN-Code: )(\d+)', 3) <== erklären ?

    den Teil :: (?:EAN-Code: )(\d+) ???? da hört's bei mir auf ..

    vielen vielen dank !!

    wie kommt man denn da dauf ?! kennst wohl jede Funktion auswendig .. ;)

    SUPER !!


  • ...
    ==> $ret = StringRegExp(FileRead($file), '(?:EAN-Code: )(\d+)', 3) <== erklären ?
    den Teil :: (?:EAN-Code: )(\d+) ???? da hört's bei mir auf ..
    ...

    Da kann ich nur empfehlen diese Seite mal anzuschauen: BugFix's Erklärung. Evtl. hilft es Dir.

    Lieben Gruß,
    Alina

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Geheime Information: ;)
    k3mrwmIBHejryPvylQSFieDF5f3VOnk6iLAVBGVhKQegrFuWr3iraNIblLweSW4WgqI0SrRbS7U5jI3sn50R4a15Cthu1bEr

  • ....und es geht natürlich immer noch was, doppelt so schnell wie BugFix^^

    Spoiler anzeigen
    [autoit]


    $string=""
    $log=""
    ;file ca. 6MB schreiben
    for $i=1 to 15
    for $s=1 to 100
    $string&=chr(random(35,127,1))
    next
    $string&=$string&@crlf
    if $i>14 then msgbox(0,$i,stringlen($string))
    next

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

    $log="----------------------------------------"&@crlf
    $log&=""&@crlf
    $log&="[08-24-2009 - 11:02:03]:"&@crlf
    $log&="Version: Ver. 2.04"&@crlf
    $log&="EAN-Code: 4022709224101"&@crlf
    $log&="Variante: 19"&@crlf
    $log&="EEPROM Format: Ver. 09.00"&@crlf
    $log&="Quarzabweichung: 7.65[s/d] abgeglichen auf +0.00[s/d]"&@crlf
    $log&="Temperatur: 24.09[°C]"&@crlf
    $log&=""&@crlf
    $log&=$log&$log
    $string&=$log

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

    Filedelete("test.log") ;datei löschen
    sleep (1000)
    filewrite("Test.log",$string) ;datei schreiben
    sleep(1000)

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

    ;File lesen und EAN suchen
    $t=timerinit()
    $string1=fileread("test.log")
    $EAN=stringmid($string1,stringinstr($string1,"EAN-Code: ",0,-1)+10,13)
    $m=timerdiff($t)
    msgbox(0,int($m)&" ms","EAN: "&$ean)

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

    $t=timerinit()
    $ean = StringRegExp(FileRead("test.log"), '(?:EAN-Code: )(\d+)', 3)
    $m=timerdiff($t)
    msgbox(0,int($m)&" ms","EAN: "&$ean)

    [/autoit]

    aber 50 ms mehr oder weniger machen den Kohl wohl auch nicht fett :rofl:

    • Offizieller Beitrag

    könntest du mir aber bitte

    ==> $ret = StringRegExp(FileRead($file), '(?:EAN-Code: )(\d+)', 3) <== erklären ?

    '(?:EAN-Code: )(\d+)' - ist das Suchmuster (Pattern)
    (?:EAN-Code: ) - erster Ausdruck in Klammern (Backreferenz) dient zum Finden des Strings (EAN...)
    ?: ist die Anweisung: diese Backreferenz im Ergebnis nicht aufführen
    (\d+) - zweite Backreferenz, ist zu berücksichtigen.
    \d bedeutet Ziffer, + ist ein Quantifier und heißt mindestens 1-mal bis beliebig oft