Ordner in Verzeichnis Struktur suchen

  • Liebe Autoit Freunde,

    ich würde gerne ein Script schreiben mit dem ich durch eine Verzeichnis-Struktur geh (+ UnterOrdner Anzahl kann variieren). Die Namen sind belibig gewählt.
    Außer ein Name, der ist auf Beendete Jobs festgelegt.
    Aufgabe des Scriptes ist, mir alle Ordner mit dem Namen Beendete Jobs zu suchen und in eine txt Datei zu schreiben (+ Datei größe)
    Irgendwie komm ich nicht so recht weiter.

    [autoit]


    FileFindFirstFile
    FileFindNextFile

    [/autoit][autoit]

    _FileListToArray()

    [/autoit]

    Bin ich damit richtig unterwegs? Oder ganz falsch? Für jeden Tip wäre ich dankbar.

    Einmal editiert, zuletzt von kingjim (18. Oktober 2010 um 19:23)

  • Ja bist damit richtig unterwegs - fehlt auch nicht mehr viel... ;)
    Im Forum hättest du mehrere Funktionen zur Dateisuche gefunden (meistens als "rekursiv" bezeichnet weil diese in der Regel mit dieser Programmiertechnik arbeiten).
    Hier mal ein Beispiel:

    Spoiler anzeigen
    [autoit]

    #include <Array.au3>

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

    $aTmp = FLwStr("C:\", "^Beendete Jobs$", 2)
    _ArrayDisplay($aTmp)

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

    ; #FUNCTION# ======================================================================================
    ; Name ..........: FLwStr()
    ; Description ...: Findet Dateien und/oder Ordner in einem Verzeichnisbaum
    ; Syntax ........: FLwStr($sSD, Const[ $sPat = '', Const[ $iF = 3]])
    ; Parameters ....: $sSD - Suchort (mehrere Suchorte durch | trennen)
    ; Const $sPat - [optional] regulärer Ausdruck für zu findende Datei/Ordnernamen (default:'')
    ; Const $iF - [optional] 1=nur Dateien, 2=nur Ordner, 3=Dateien+Ordner (default:3)
    ; Return values .: Success - Return Array with Matches with $Array[0] = Count
    ; Failure - Return "" and set @error
    ; Author ........: AspirinJunkie
    ; Remarks .......: Funktionsweise ist iterativ - nicht rekursiv
    ; Example .......: Yes
    ; #include <Array.au3>
    ; $aTmp = FLwStr(@WindowsDir & '|' & @ProgramFilesDir, "^Temp$", 2)
    ; _ArrayDisplay($aTmp)
    ; =================================================================================================
    Func FLwStr($sSD, Const $sPat = '', Const $iF = 3)
    ;by AspirinJunkie
    Local $sRet = "", $sSubD = ""
    For $i in StringSplit($sSD, '|', 2)
    If StringRight($i, 1) = '\' Then $i = StringTrimRight($i, 1)
    If Not FileExists($i) Then Return SetError(2, 0, "")
    $sSubD &= '|' & $i
    Next
    Local $FFFF, $FFNF, $sDir, $iC
    Local $aD, $hDLL = DllOpen('kernel32.dll')
    If Not ($iF = 3 Or $iF = 1 Or $iF = 2) Then Return SetError(3, 0, "")
    Do
    $iC = StringInStr($sSubD, '|', 2, -1)
    If @error Or $iC = 0 Then ExitLoop
    $iC = StringLen($sSubD) - $iC
    $sDir = StringRight($sSubD, $iC)
    $sSubD = StringTrimRight($sSubD, $iC + 1)
    $FFFF = FileFindFirstFile($sDir & '\*')
    If $FFFF <> -1 Then
    Do
    $FFNF = FileFindNextFile($FFFF)
    If @error Then ExitLoop
    If @extended Then
    If BitAND(StringRegExp($FFNF, $sPat) * 2, $iF) Then $sRet &= $sDir & '\' & $FFNF & '\|'
    $aD = DllCall($hDLL, 'dword', 'GetFileAttributesW', 'wstr', $sDir & '\' & $FFNF)
    If @error And BitAND($aD[0],0x400) Then ContinueLoop
    $sSubD &= '|' & $sDir & '\' & $FFNF
    ElseIf BitAND(StringRegExp($FFNF, $sPat), $iF) Then
    $sRet &= $sDir & '\' & $FFNF & '|'
    EndIf
    Until 0
    FileClose($FFFF)
    EndIf
    Until 0
    DllClose($hDLL)
    Return StringSplit(StringTrimRight($sRet, 1), '|')
    EndFunc

    [/autoit]

    Die ^ und $ stehen bei regulären Ausdrücken für Stringanfang (bzw. Zeilenanfang) und Stringende.
    Würde man dies nicht eintragen würden auch Ordner gefunden welche z.B. "Blabla Beendete Jobs15" heißen.
    Die Verwendung der regulären Ausdrücke mag für deinen Fall vielleicht etwas overdosed sein aber es gibt wie gesagt im Forum hier noch mehr als genug Funktionen welche dein Ziel erreichen.

    Einmal editiert, zuletzt von AspirinJunkie (19. Oktober 2010 um 10:26)

  • ähhhm...also hab gerade angefangen mit Autoit.
    Nicht böse sein, dein Script ist super, allerdings "versteh" ich es noch nicht genau ;)

  • Um es zu benutzen musst du den "bösen" Teil auch nicht verstehen.
    Das ist alles verpackt in der Funktion FLwStr().
    Eigentlich brauchen dich nur die ersten 3 Zeilen zu interessieren.
    Du rufst die Funktion mit den entsprechenden Suchparametern auf, bekommst ein Array zurück und lässt es mit der Funktion _ArrayDisplay anzeigen.

  • Ich mag aber auch den Bösen Teil Verstehen ;)
    Und wie bekomm ich das angezeigte Array in eine Text File gepackt?

  • [autoit]


    #Include <File.au3>
    _FileWriteFromArray($File, $a_Array [, $i_Base = 0 [, $i_UBound = 0]])

    [/autoit]

    Parameters
    $File
    String path of the file to write to, or a file handle returned
    from FileOpen().

    $a_Array
    The array to be written to the file.

    $i_Base
    [optional] Start Array index to read, normally set to 0 or 1.
    Default=0

    $i_Ubound
    [optional] Set to the last record you want to write to the File.
    default=0 - whole array.

  • Ich denke mal das ist eher ne Funktion die ein Anfänger nicht sofort versteht.
    Aber mach dir keine Sorgen das kommt mit der Zeit ;)

    Um ein Array in ein Textfile zu schreiben kannste das verwenden:

    [autoit]

    _FileWriteFromArray()

    [/autoit]
  • habs so eben gemacht ;) den Rest bekomm ich auch noch hin ;)

    VIELEN DANK

    Ich denke mal das ist eher ne Funktion die ein Anfänger nicht sofort versteht.
    Aber mach dir keine Sorgen das kommt mit der Zeit ;)

    Um ein Array in ein Textfile zu schreiben kannste das verwenden:

    [autoit]

    _FileWriteFromArray()

    [/autoit]
  • Ich mag aber auch den Bösen Teil Verstehen ;)

    Ok. Ich werde nicht jede Zeile einzeln erklären - das wäre zu viel des Guten.
    Aber ein paar prinzipielle Teilaufgaben und wie sie gelöst werden versuche ich mal ansatzweise zu erklären:

    Also Ziel ist alle Dateien und Ordner in einem Ordner durchzugehen und jedes Element auf Namensübereinstimmung mit dem Suchpattern hin zu untersuchen.
    Teilaufgabe: Alle Dateien und Ordner durchgehen und dabei auch alle Unterordner berücksichtigen:
    Wir starten mit FileFindFirstFile (39) und FileFindNextFile. Dies liefert uns alle Elemente in einem Ordner welche wir nun in der Do-Schleife (Zeile 41-52) einzeln durchgehen bis es keine Elemente mehr gibt (Zeile 43). Bei jedem Element muss unterschieden werden ob es sich um eine Datei oder einen Ordner handelt (Zeile 44). Wenn jetzt noch das Suchpattern stimmt und außerdem noch das entsprechende Flag vom User gesetzt ist (Zeile 45 bzw. 49) wird der Dateiname an den String $sRet drangehängt (Zeile 45 bzw. 50 ) welcher uns als Zwischenspeicher dient für die Ausgabe.
    Da wir aber alle Unterordner durchsuchen wollen wird jeder Ordner der gefunden wird einem weiteren Zwischenspeicher namens $sSubD hinzugefügt (Zeile 48).
    Wir lassen das Skript in einer Endlosschleife (Zeile 33-55) diese Ordner solange abarbeiten bis keine Ordnernamen mehr in $sSubD vorhanden sind (Zeile 23) da wir bei jedem Ordneraufruf diesen wieder aus $sSubD entfernen (Zeile 36-38). Diese Vorgehensweise unterscheidet sich von der rekursiven bei der bei jedem Ordner die Funktion nochmal mit diesem als Parameter aufgerufen wird.
    Am Ende haben wir im String $sRet alle übereinstimmenden Funde durch "|" getrennt liegen.
    Diese werden dann als Array gewandelt und zurückgegeben (Zeile 57).
    Der Rest in dieser Funktion sind eigentlich nur Sicherheitsabfragen und Initialisierungen.
    So ist z.B. Zeile 25-29 dafür da mehrere Suchorte, welche der User angegeben hat, zu verarbeiten und sie $sSubD hinzuzufügen so dass sie dann alle abgearbeitet werden.

    Einmal editiert, zuletzt von AspirinJunkie (19. Oktober 2010 um 10:30)