2 Verzeichnisse vergleichen und ein Array mit zeitlichen Unterschieden retournieren

  • Hallo allerseits,

    Ich muss mich mit folgendem Problem beschäftigen:

    Es sollte eine Funktion sein, die als Übergabewert 2 Pfade und einen Zeitunterschied hat. Daraus sollte die Funktion feststellen, ob die Datein in beiden Verzeichnissen vorhanden sind (ist kein Problem) und ob die verglichenen Dateien innerhalb des übergebenen Zeitunterschieds sind. Sollte es Unterschiede geben (d.h. das zu überprüfende File ist über den vorgegebenen Zeitunterschied), sollten die unterschiedlichen Files (mit gesamten Pfad) mittels Array an die Funktion retourniert werden.

    Mir fehlt für die Überprüfungen einfach der Ansatz - Alzheimer!!!!! machts möglich.


    Vielleicht kann mir jemand helfen - wäre toll.


    LG

    Merlin

    Einmal editiert, zuletzt von mr_merlin (8. November 2012 um 11:16) aus folgendem Grund: Problem gelöst.

  • guck dir mal die UDF Funktion "_FileListToArray" an ...

    die kannst du entsprechend parametrieren, dass entwerde File's oder Folder zurückgegeben werden ..
    oder beides .. ich finde einzeln aber irgend wie geschickter.... dann must nicht später noch mal sortieren ..

    dann hast du 2 array's .. Pro Ordner/ebene

    das File array lässt du mit "FileGetTime" die Zeit vergleichen ..

    .. für die Unterordner musst du dir halt ne Funktion bauen, die du dann Recursiv abarbeitest ...

    die Ergebnisse/ Unterschiede würde ich in ein Log ablegen ..

    und anschliessend von einer getrennten Funktion verschieben lassen ..
    Dann kannst du erst mal gut debuggen ohne immer wieder eine Testsituation generieren zu müssen ..

  • Danke vorerst für deine raschen Ausführungen.

    Das mit _FileListToArray ist ja nicht wirklich das Problem. Ich wollte (soweit dies möglich ist) beide Pfade in 2 Arrays einlesen, diese gegeneinander mit dem geforderten Zeitunterschied vergleichen und jene Files, die außerhalb des Zeitunterschiedes sind, in ein neues Array einlesen, welches dann als Übergabewert der Funktion mitgegeben wird. Wenn möglich (das ist auch der Grund meiner Anfrage) möchte ich keine Temp-Files schreiben lassen (so täte es ja auch jetzt schon funktionieren), sondern wirklich alles sauber in Arrays abhandeln. Die große Schwierigkeit daran ist es dazu noch, das alles rekursiv (also ohne des Wissens, wie viele Sub-Directories noch bestehen) abzuarbeiten. Die Struktur der Unterverzeichnisse sind jedoch gleich (nur das Root-Verzeichnis heißt anders).

    lg
    mr_merlin

  • Hallo Merlin,

    ich habe mich mal bei Oscar bedient und daraus meinen Lösungsvorschlag entwickelt:

    Spoiler anzeigen
    [autoit]

    #include <Array.au3>
    #include <Date.au3>

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

    $aChecked = _Check('c:\test1', 'c:\test2', 5)
    _ArrayDisplay($aChecked)

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

    Func _Check($sOrdner1, $sOrdner2, $iDays)
    Local $aReturn1 = _RecursiveFileListToArray($sOrdner1, '', 1, 1, @CRLF, $sOrdner1) ; Alle Dateien im ausgewählten Ordner und Unterordnern)
    Local $aReturn2 = _RecursiveFileListToArray($sOrdner2, '', 1, 1, @CRLF, $sOrdner2) ; Alle Dateien im ausgewählten Ordner und Unterordnern)
    Local $aResult[$aReturn1[0] + $aReturn2[0]][4]
    Local $iNew = 1
    For $i = 1 To $aReturn1[0]
    $iPos = _ArraySearch($aReturn2, $aReturn1[$i])
    If $iPos > -1 Then
    ;datei existiert auch um 2. Verzeichnis
    $sDate1 = StringRegExpReplace(FileGetTime($sOrdner1 & $aReturn1[$i], 0, 1), '(\d{4})(\d{2})(\d{2})(.*)', '$1/$2/$3')
    $sDate2 = StringRegExpReplace(FileGetTime($sOrdner2 & $aReturn2[$iPos], 0, 1), '(\d{4})(\d{2})(\d{2})(.*)', '$1/$2/$3')
    $iDiffDays = _DateDiff('D', $sDate1, $sDate2)
    ;ConsoleWrite($aReturn1[$i] & " " & $sDate1 & " " & $sDate2 & " " & $iDiffDays & @CRLF)
    If $iDiffDays > $iDays Or ($iDiffDays * - 1) > $iDays Then
    $aResult[$iNew][0] = $aReturn1[$i]
    $aResult[$iNew][1] = $sDate1
    $aResult[$iNew][2] = $sDate2
    $aResult[$iNew][3] = $iDiffDays
    $iNew += 1
    EndIf
    _ArrayDelete($aReturn2, $iPos) ;damit in $aReturn2 nur Dateien übrigbleiben die nicht i $aReturn1 sind
    $aReturn2[0] -= 1
    Else
    $aResult[$iNew][0] = $aReturn1[$i]
    $aResult[$iNew][2] = ''
    $aResult[$iNew][3] = "<-1>" ;Kenzeichnung dass Datei nur in 1
    $iNew += 1
    EndIf
    Next
    _ArrayDisplay($aResult)
    For $i = 1 To $aReturn2[0]
    $aResult[$iNew][0] = $aReturn2[$i]
    $sDate2 = StringRegExpReplace(FileGetTime($sOrdner2 & $aReturn2[$i], 0, 1), '(\d{4})(\d{2})(\d{2})(.*)', '$1/$2/$3')
    $aResult[$iNew][1] = ''
    $aResult[$iNew][2] = $sDate2
    $aResult[$iNew][3] = "<-2>" ;Kenzeichnung dass Datei nur in 2
    $iNew += 1
    Next
    $aResult[0][0] = $iNew - 1
    ReDim $aResult[$iNew][4]
    $aResult[0][1] = $sOrdner1
    $aResult[0][2] = $sOrdner2
    $aResult[0][3] = "Differenz"
    Return $aResult
    EndFunc ;==>_Check

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

    ;===============================================================================
    ; Function Name: _RecursiveFileListToArray($sPath, $sPattern, $iFlag = 0, $iFormat = 1, $sDelim = @CRLF)
    ; Description:: gibt Verzeichnisse und/oder Dateien (rekursiv) zurück, die
    ; einem RegExp-Pattern entsprechen
    ; Parameter(s): $sPath = Startverzeichnis
    ; $sPattern = ein beliebiges RexExp-Pattern für die Auswahl
    ; $iFlag = Auswahl
    ; 0 = Dateien & Verzeichnisse
    ; 1 = nur Dateien
    ; 2 = nur Verzeichnisse
    ; $iFormat = Rückgabeformat
    ; 0 = String
    ; 1 = Array mit [0] = Anzahl
    ; 2 = Nullbasiertes Array
    ; $sDelim = Trennzeichen für die String-Rückgabe
    ; Requirement(s): AutoIt 3.3.0.0
    ; Return Value(s): Array/String mit den gefundenen Dateien/Verzeichnissen
    ; Author(s): Oscar (http://www.autoit.de)
    ; Anregungen von: bernd670 (http://www.autoit.de)
    ;modified: autoBert um den ursprünglich übergebenen Ordner wegzulassen
    ;===============================================================================
    Func _RecursiveFileListToArray($sPath, $sPattern, $iFlag = 0, $iFormat = 1, $sDelim = @CRLF, $sExlude = '')
    Local $hSearch, $sFile, $sReturn = ''
    If StringRight($sPath, 1) <> '\' Then $sPath &= '\'
    $hSearch = FileFindFirstFile($sPath & '*.*')
    If @error Or $hSearch = -1 Then Return SetError(1, 0, $sReturn)
    While True
    $sFile = FileFindNextFile($hSearch)
    If @error Then ExitLoop
    If StringInStr(FileGetAttrib($sPath & $sFile), 'D') Then
    If StringRegExp($sPath & $sFile, $sPattern) And ($iFlag = 0 Or $iFlag = 2) Then $sReturn &= $sPath & $sFile & '\' & $sDelim
    $sReturn &= _RecursiveFileListToArray($sPath & $sFile & '\', $sPattern, $iFlag, 0, $sDelim, $sExlude)
    ContinueLoop
    EndIf
    If StringRegExp($sFile, $sPattern) And ($iFlag = 0 Or $iFlag = 1) Then $sReturn &= $sPath & $sFile & $sDelim
    WEnd
    FileClose($hSearch)
    $sReturn = StringReplace($sReturn, $sExlude, "")
    If $iFormat Then Return StringSplit(StringTrimRight($sReturn, StringLen($sDelim)), $sDelim, $iFormat)
    Return $sReturn
    EndFunc ;==>_RecursiveFileListToArray

    [/autoit]

    edit: Skript abgeändert so dass es jetzt egal ist in welchem der beiden Ordner sich die neuere Version befindet (Kennzeichnung durch positive der negatve Anzahl der Tage).

    Da dadurch Fehlinterpretationen vorkommen konnten die Kennzeichnung für fehlende Dateien geändert: "<-1>" Datei existiert nur in Ordner 1, "<-2>" Datei existiert nur in Ordner 2.
    Ausserdem werden die ermittelten Datumsangaben jetzt im Ergebnisarray gespechert.

    mfg autoBert

    2 Mal editiert, zuletzt von autoBert (7. November 2012 um 19:05)

  • Hi autoBert,

    habe leider noch keine Zeit, dein Skript zu testen - aber es ist WIEDER EINMAL genau der Richtige weg. Du hast mir jetzt schon zum 2. Mal wirklich geholfen. Weiß nicht, wie ich mich außer auf diesem Weg, bei dir bedanken kann.
    Melde mich Morgen.
    Gruß
    Merlin

  • Weiß nicht, wie ich mich außer auf diesem Weg, bei dir bedanken kann.


    Du kannst (und solltest) dir die Mühe machen Testdaten zu generieren und das erwartete Ergebnis davon zu bestimmen. Wenn es dann mit meiner Ausgabe des Arrays übereinstimmt meldest du die Func _Check als OK und stellst den Beitrag auf gelöst.

    Ich habe noch eimal Änderungen am Skript gemacht, du musst also den neuen Sourcecode dazu nehmem.

    mfg autoBert

  • Hallo autoBert,
    zum Feststellen, ob Files in den 2 Verzeichnissen existieren und ob eine Datumsdifferenz besteht, ist die Funktion ideal.
    Ich habe versucht, die Funktion insoweit abzuändern, sodass nicht die Tage sondern die Stundendifferenz angezeigt wird (dies benötige ich eigentlich - es sollen ja nur Stunden der Funktion übergeben werden). Leider bekomme ich nichts zurück. Ich habe FileGetTime und _DateDiff abgeändert, ich bekomme jedoch irgendwie kein Ergebnis.
    Hast du vielleicht dazu noch einen Ansatzpunkt?
    lg
    Merlin