Text zählen

  • Hallo
    Angenommen ich habe so ein Stück log

    Spoiler anzeigen


    wie bekomme ich herraus welche IP wie oft zugegriffen hat
    also z.B so 79.202.35.161 14 mal
    91.141.1.22 20 mal

    Mir fält leider kein ansatz ein. :(

    Einmal editiert, zuletzt von senden9 (14. April 2009 um 11:58)

  • Schau dir mal die _Array Funktionen an:

    Spoiler anzeigen
    [autoit]

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

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

    Global $aListe, $aTmp, $aIPs, $aErg[1][2]

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

    _FileReadToArray(@scriptdir & "/ip_zaehler.txt", $aListe)

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

    If Not @error Then
    $aIPs = _ArrayUnique($aListe, 1, 1)
    ReDim $aErg[Ubound($aIPs)][2]

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

    For $i = 1 To $aIPs[0]
    $aTmp = _ArrayFindAll($aListe, $aIPs[$i])
    $aErg[$i][1] = UBound($aTmp)
    $aErg[$i][0] = $aIPs[$i]
    Next

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

    _ArrayDisplay($aErg)
    EndIf

    [/autoit]
  • hab auch einen:

    Spoiler anzeigen
    [autoit]

    #include <Array.au3>
    #include <file.au3>
    Dim $aList
    _FileReadToArray(@ScriptDir&"\list.txt",$aList)
    _ArraySort($aList)
    $text = FileOpen("ergebniss.txt",1)
    $x = 1
    For $i = 1 To $aList[0]
    $ip = $aList[$i]
    Select
    Case $ip = $aList[$i-1]
    $x += 1
    Case Else
    FileWriteLine($text,$aList[$i-1] & " = "& $x)
    $x = 1
    EndSelect
    Next
    FileClose($text)

    [/autoit]

    MfG Schnuffel

    "Sarkasmus ist die niedrigste Form des Witzes, aber die höchste Form der Intelligenz."
    Val McDermid

    ein paar Infos ...

    Wer mehr als "nur" Hilfe benötigt, kann sich gern im Forum "Programmieranfragen" an uns wenden. Wir helfen in allen Fällen, die die Forenregeln zulassen.

    Für schnelle Hilfe benötigen wir ein ! lauffähiges ! Script, dass wir als Demonstration des Problems testen können. Wer von uns erwartet ein Teilscript erstmal lauffähig zu bekommen, der hat
    1. keine wirkliche Not
    2. keinen Respekt vor Menschen die ihm in ihrer Freizeit Ihre Hilfe anbieten
    3. oder ist einfach nur faul und meint wir coden das für ihn

    In solchen Fällen erlaube ich mir, die Anfrage einfach zu ignorieren. ;)

    • Offizieller Beitrag

    Mist, schon wieder zu spät! ^^

    Aber ich poste trotzdem mal meine Variante:

    Spoiler anzeigen
    [autoit]


    #include <Array.au3>
    Global $hFile = FileOpen(@ScriptDir & '\logdatei.log', 0)
    Global $iCount = 0
    If $hFile <> -1 Then
    Global $aIPAdress[$iCount + 1][2]
    While True
    $sTmp = FileReadLine($hFile)
    If @error Then ExitLoop
    For $i = 0 To UBound($aIPAdress) - 1
    If $sTmp = $aIPAdress[$i][0] Then
    $aIPAdress[$i][1] += 1
    ContinueLoop 2
    EndIf
    Next
    $aIPAdress[$iCount][0] = $sTmp
    $aIPAdress[$iCount][1] = 1
    $iCount += 1
    ReDim $aIPAdress[$iCount + 1][2]
    WEnd
    FileClose($hFile)
    ReDim $aIPAdress[$iCount][2]
    _ArraySort($aIPAdress, 1, 0, 0, 1)
    _ArrayDisplay($aIPAdress)
    EndIf

    [/autoit]


    Eigentlich ohne Includes. Hier nur zum sortieren und anzeigen des Arrays.

  • Ne Andere Möglichkeit wäre
    - Array erzeugen mit allen Adressen
    - Mit _ArrayUnique ein weitere Array erzeugen wo jede Adresse nur einmal vorkommt.
    - Dann mit _ArrayFindAll und ner For-Schleife alle Werte des _ArrayUnique durchlaufen lassen.
    - Ergebnisse zählen.
    - Fertig

    Nur ich glaube duch die vielen Arrayfunktionen ist diese Lösung langsamer als die anderen Beiden.

    MfG
    Der_Doc

  • Ne Andere Möglichkeit wäre
    - Array erzeugen mit allen Adressen
    - Mit _ArrayUnique ein weitere Array erzeugen wo jede Adresse nur einmal vorkommt.
    - Dann mit _ArrayFindAll und ner For-Schleife alle Werte des _ArrayUnique durchlaufen lassen.
    - Ergebnisse zählen.
    - Fertig

    Nur ich glaube duch die vielen Arrayfunktionen ist diese Lösung langsamer als die anderen Beiden.


    Meinst du etwa so: https://autoit.de/index.php?page…87250#post87250 :D
    Das ist mit Sicherheit langsamer, kommt halt auf die Menge der auszuwertenden Daten an, wenn das nicht der entscheidende Faktor ist, dann lieber übsersichtlich und langsamer, als das Rad neu zu erfinden.

    [EDIT]
    Habe mal kurz einen Geschwindigkeitstest gemacht:

    IP-Adressen: 4081
    Schnuffel: 560ms
    Oscar: 1013ms
    Meine Version 18684ms :whistling:

    Schnuffel:
    Deine Version funktioniert nur wenn ich zu _ArraySort($aList,1,1) "update".
    Sonst funktioniert die Schleife nicht, da der Zähler mitsortiert wird.

    3 Mal editiert, zuletzt von Stilgar (14. April 2009 um 09:56)

  • Hi,
    das meins die langsamste Methode ist war ja klar, manchmal braucht man aber alles in einem Array usw. ;)

    Wenn dann nimm aber bei Oscar mal das ArrayDysplay und und Sort raus, dann ist es bistimmt schneller als das von Schnuffel ;)
    Reiner Autoitcode und kommt ohne UDF aus.

    MfG
    Der_Doc

  • Hi,
    das meins die langsamste Methode ist war ja klar, manchmal braucht man aber alles in einem Array usw. ;)

    Wenn dann nimm aber bei Oscar mal das ArrayDysplay und und Sort raus, dann ist es bistimmt schneller als das von Schnuffel ;)
    Reiner Autoitcode und kommt ohne UDF aus.

    MfG
    Der_Doc

    Das hatte ich schon gemacht:

    Spoiler anzeigen
    [autoit]

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

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

    $Timer = TimerInit()
    _F1()
    ConsoleWrite( Round(TimerDiff($Timer)) & @crlf)

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

    $Timer = TimerInit()
    _F2()
    ConsoleWrite( Round(TimerDiff($Timer)) & @crlf)

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

    $Timer = TimerInit()
    _F3()
    ConsoleWrite( Round(TimerDiff($Timer)) & @crlf)

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

    exit

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

    Func _F3()
    Local $hFile = FileOpen(@scriptdir & "/ip_zaehler.txt", 0)
    Local $iCount = 0
    If $hFile <> -1 Then
    Local $aIPAdress[$iCount + 1][2]
    While True
    $sTmp = FileReadLine($hFile)
    If @error Then ExitLoop
    For $i = 0 To UBound($aIPAdress) - 1
    If $sTmp = $aIPAdress[$i][0] Then
    $aIPAdress[$i][1] += 1
    ContinueLoop 2
    EndIf
    Next
    $aIPAdress[$iCount][0] = $sTmp
    $aIPAdress[$iCount][1] = 1
    $iCount += 1
    ReDim $aIPAdress[$iCount + 1][2]
    WEnd
    FileClose($hFile)
    ReDim $aIPAdress[$iCount][2]
    ;_ArraySort($aIPAdress, 1, 0, 0, 1)
    ;_ArrayDisplay($aIPAdress)
    EndIf

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

    EndFunc ;==>_F3
    ;===============================================================================
    Func _F2()

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

    Local $aList
    _FileReadToArray(@scriptdir & "\ip_zaehler.txt", $aList)
    _ArraySort($aList,1,1)
    $text = FileOpen(@scriptdir & "\ergebniss.txt", 2)
    $x = 1
    For $i = 1 To $aList[0]
    $ip = $aList[$i]
    Select
    Case $ip = $aList[$i - 1]
    $x += 1
    Case Else
    FileWriteLine($text, $aList[$i - 1] & " = " & $x)
    $x = 1
    EndSelect
    Next
    FileClose($text)

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

    EndFunc ;==>_F2
    ;===============================================================================
    Func _F1()

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

    Local $aListe, $aTmp, $aIPs, $aErg[1][2]

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

    _FileReadToArray(@scriptdir & "\ip_zaehler.txt", $aListe)

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

    If Not @error Then
    $aIPs = _ArrayUnique($aListe, 1, 1)
    ReDim $aErg[Ubound($aIPs)][2]

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

    For $i = 1 To $aIPs[0]
    $aTmp = _ArrayFindAll($aListe, $aIPs[$i])
    $aErg[$i][1] = UBound($aTmp)
    $aErg[$i][0] = $aIPs[$i]
    Next

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

    ;_ArrayDisplay($aErg)
    EndIf

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

    EndFunc ;==>_F1

    [/autoit]
    • Offizieller Beitrag

    Stilgar: Teste doch mal diese Version:

    Spoiler anzeigen
    [autoit]


    #include <Array.au3>
    Global $aFile = StringSplit(FileRead(@scriptdir & '/ip_zaehler.txt'), @CRLF, 1)
    Global $iCount = 0
    If $aFile[0] > 1 Then
    Global $aIPAdress[$aFile[0]][2]
    For $j = 1 To $aFile[0]
    For $i = 0 To UBound($aIPAdress) - 1
    If $aFile[$j] = $aIPAdress[$i][0] Then
    $aIPAdress[$i][1] += 1
    ContinueLoop 2
    EndIf
    Next
    $aIPAdress[$iCount][0] = $aFile[$j]
    $aIPAdress[$iCount][1] = 1
    $iCount += 1
    Next
    ReDim $aIPAdress[$iCount][2]
    _ArraySort($aIPAdress, 1, 0, 0, 1)
    _ArrayDisplay($aIPAdress)
    EndIf

    [/autoit]
  • Schnell und ohne Array's

    Spoiler anzeigen
    [autoit]

    $start = TimerInit()
    $ausgabe = ""
    $gesamt = FileRead(@scriptdir & '/ip_zaehler.txt')
    $FileID = FileOpen(@scriptdir & '/ip_zaehler.txt',0)
    While 1
    $line = FileReadLine($fileID)
    If @error = -1 Then ExitLoop
    If Not StringInStr($ausgabe,$line,2) Then
    StringReplace($gesamt,$line,$line,0,2)
    $ausgabe &= $line & ", " & @extended & @CRLF
    EndIf
    Wend
    FileClose($fileID)
    If StringRight($ausgabe,2) = @CRLF Then $ausgabe = StringLeft($ausgabe,StringLen($ausgabe)-2)
    MsgBox (0,"Dauer = " & Int(TimerDiff($start) + 0.5) & "ms",$ausgabe)

    [/autoit]

    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"

    Einmal editiert, zuletzt von Micha_he (14. April 2009 um 17:57)

  • :rofl: dabei hab ich gar nicht auf Speed optimiert, sondern einfach so geschrieben wie ich halt gedacht habe.

    (Bin ich jetzt deswegen ein "Schnelldenker" ??? ) :rofl::rofl::rofl:

    MfG Schnuffel

    "Sarkasmus ist die niedrigste Form des Witzes, aber die höchste Form der Intelligenz."
    Val McDermid

    ein paar Infos ...

    Wer mehr als "nur" Hilfe benötigt, kann sich gern im Forum "Programmieranfragen" an uns wenden. Wir helfen in allen Fällen, die die Forenregeln zulassen.

    Für schnelle Hilfe benötigen wir ein ! lauffähiges ! Script, dass wir als Demonstration des Problems testen können. Wer von uns erwartet ein Teilscript erstmal lauffähig zu bekommen, der hat
    1. keine wirkliche Not
    2. keinen Respekt vor Menschen die ihm in ihrer Freizeit Ihre Hilfe anbieten
    3. oder ist einfach nur faul und meint wir coden das für ihn

    In solchen Fällen erlaube ich mir, die Anfrage einfach zu ignorieren. ;)

    Einmal editiert, zuletzt von Schnuffel (14. April 2009 um 21:46)

    • Offizieller Beitrag

    Na, das sieht doch schon ganz gut aus.

    Wie schneidet denn diese Variante ab?

    Spoiler anzeigen
    [autoit]


    #include <Array.au3>
    $oDictionary = ObjCreate('Scripting.Dictionary')
    $aFile = StringSplit(FileRead(@ScriptDir & '/ip_zaehler.txt'), @CRLF, 1)
    For $i = 1 To $aFile[0]
    If $oDictionary.Exists($aFile[$i]) Then
    $iVal = $oDictionary.Item($aFile[$i])
    $oDictionary.Item($aFile[$i]) = $iVal + 1
    Else
    $oDictionary.Add($aFile[$i], 1)
    EndIf
    Next
    Global $aIPAdress[$oDictionary.Count][2], $iCount = 0
    For $strKey In $oDictionary.Keys
    $aIPAdress[$iCount][0] = $strKey
    $aIPAdress[$iCount][1] = $oDictionary.Item($strKey)
    $iCount += 1
    Next
    _ArraySort($aIPAdress, 1, 0, 0, 1)
    _ArrayDisplay($aIPAdress)

    [/autoit]
    • Offizieller Beitrag

    Leute, das muß doch schneller gehen :D
    Und was ist geeigneter für große Datenmengen als... SQLite ;)

    Grob geschätzt 60% Zeitersparnis. ( und ausserdem sortiert nach Häufigkeit :P )

    [autoit]

    #include <File.au3>
    #include <SQLite.au3>
    #include <SQLite.dll.au3>
    Func _sql_count_ip()
    Local $file = @ScriptDir & '\test_ip.txt', $arIP
    _FileReadToArray($file, $arIP)
    Local $tableStr = "CREATE TABLE tblTEST ('ip');"
    Local $insertStr = ''
    For $i = 1 To UBound($arIP) -1
    $insertStr &= "INSERT INTO tblTEST VALUES ('" & $arIP[$i] & "');"
    Next

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

    _SQLite_Startup ()
    $hSQL = _SQLite_Open ()
    _SQLite_Exec ( $hSQL, $tableStr & $insertStr )

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

    Local $hQuery, $aRow, $result = '', $fh
    _SQlite_Query ( $hSQL, "SELECT ip,COUNT(ip) FROM tblTEST GROUP BY ip ORDER BY COUNT(ip) DESC;", $hQuery )

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

    While _SQLite_FetchData ($hQuery, $aRow) = $SQLITE_OK
    $result &= $aRow[0] & @TAB & $aRow[1] & @CRLF
    ;~ ConsoleWrite($aRow[0] & @TAB & $aRow[1] & @CRLF)
    WEnd
    $fh = FileOpen(@ScriptDir & '\test_ip_out.txt', 1)
    FileWrite($fh, $result)
    FileClose($fh)
    _SQLite_Exec ( $hSQL, "DROP TABLE tblTEST;" )
    _SQLite_Close ()
    _SQLite_Shutdown ()
    EndFunc

    [/autoit]

    Edit: Was allerdings wieder 2/3 ausbremst, ist die Initialisierung der SQLite Dll ;)

  • Wieder Vergleich mit 10 Durchläufen und 4080 Adressen.

    Im Durchschnitt:
    Schnuffel: 510.9
    Micha_he: 765.2
    Oscar I: 745.2
    Oscar II: 2213.2 (ohne ArraySort)
    Oscar III: 194.2 (ohne ArraySort)
    BugFix: 324.7 (wenn die Daten schon in der DB drinn sind dauert die Auswertung nur noch 12.4ms)

    2 Mal editiert, zuletzt von Stilgar (15. April 2009 um 22:31)

    • Offizieller Beitrag

    (wenn die Daten schon in der DB drinn sind dauert die Auswertung nur noch 12.4ms)


    Ja, dann ist es wirklich sauschnell. Das Einfügen der Daten ist der Pferdefuß.
    _FileReadToArray ist hier die Bremse. Ich hab jetzt mal die Funktion direkt mit der Erstellung des SQL-Insertstring verknüpft. Bringt bei mir einen schönen Zeitgewinn. Könnte evtl. an die Werte der Objekt-Version heranreichen.

    [autoit]

    Func _sql_count_ip()
    Local $fh = FileOpen(@ScriptDir & '\test_ip.txt', 0)
    Local $insertStr = '', $hSQL
    Local $aFile = StringStripWS(FileRead($fh, 2)
    If StringInStr($aFile, @LF) Then
    $aFile = StringSplit(StringStripCR($aFile), @LF, 2)
    ElseIf StringInStr($aFile, @CR) Then
    $aFile = StringSplit($aFile, @CR, 2)
    EndIf
    For $i = 0 To UBound($aFile) -1
    $insertStr &= "INSERT INTO tblTEST VALUES ('" & $aFile[$i] & "');"
    Next
    FileClose($fh)

    _SQLite_Startup ()
    $hSQL = _SQLite_Open ()
    _SQLite_Exec ( $hSQL, "CREATE TABLE tblTEST ('ip');" & $insertStr )

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

    Local $hQuery, $aRow, $result = ''
    _SQlite_Query ( $hSQL, "SELECT ip,COUNT(ip) FROM tblTEST GROUP BY ip ORDER BY COUNT(ip) DESC;", $hQuery )

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

    While _SQLite_FetchData ($hQuery, $aRow) = $SQLITE_OK
    ;~ $result &= $aRow[0] & @TAB & $aRow[1] & @CRLF
    ConsoleWrite($aRow[0] & @TAB & $aRow[1] & @CRLF)
    WEnd
    $fh = FileOpen(@ScriptDir & '\test_ip_out.txt', 2)
    FileWrite($fh, $result)
    FileClose($fh)
    _SQLite_Exec ( $hSQL, "DROP TABLE tblTEST;" )
    _SQLite_Close ()
    _SQLite_Shutdown ()
    EndFunc

    [/autoit]