Loop (Dateien & Ordner)

Ruft bestimmte Dateien oder Ordner einzeln ab.

Neue Syntax [v1.1.21+]

Loop, Files, DateiMuster , Modus

Parameter

Files

Das direkt geschriebene Wort Files (nicht Groß-/Kleinschreibung-sensitiv). Dieser Parameter darf weder eine Variable noch ein Ausdruck sein.

DateiMuster

Name einer Datei oder eines Ordners, oder ein Platzhaltermuster wie C:\Temp\*.tmp. Wenn kein absoluter Pfad angegeben ist, wird DateiMuster im A_WorkingDir-Verzeichnis vermutet.

Sowohl Sternchen als auch Fragezeichen werden als Platzhalter unterstützt. Eine Übereinstimmung erfolgt, wenn das Suchmuster entweder im langen/normalen oder 8.3-kurzen Dateinamen erscheint.

Wenn dieser Parameter eine einzelne Datei oder ein Ordner ist (also ohne Platzhalter), und enthält Modus ein R, werden mehrere Übereinstimmungen gefunden, wenn der angegebene Dateiname in mehreren Ordnern vorkommt.

Suchmuster länger als 259 Zeichen können aufgrund von Systemlimitierungen (MAX_PATH) dazu führen, dass keine Dateien gefunden werden. Diese Limitierung kann mithilfe des Langer-Pfad-Präfixes \\?\ umgangen werden, allerdings muss dabei einiges beachtet werden.

Modus

Wenn dieser Parameter weggelassen wird oder leer ist, werden nur Dateien einbezogen und Unterverzeichnisse nicht rekursiv durchwandert. Ansonsten können Sie einen oder mehrere der folgenden Buchstaben angeben:

Alte Syntax

Veraltet: Diese Syntax ist nicht für neue Skripte empfohlen. Verwenden Sie stattdessen die neue Syntax.

Loop, DateiMuster , OrdnerEinbeziehen?, Rekursiv?

Parameter

DateiMuster

Name einer Datei oder eines Ordners, oder ein Platzhaltermuster wie C:\Temp\*.tmp. Wenn kein absoluter Pfad angegeben ist, wird DateiMuster im A_WorkingDir-Verzeichnis vermutet.

Sowohl Sternchen als auch Fragezeichen werden als Platzhalter unterstützt. Eine Übereinstimmung erfolgt, wenn das Suchmuster entweder im langen/normalen oder 8.3-kurzen Dateinamen erscheint.

Wenn dieser Parameter eine einzelne Datei oder ein Ordner ist (also ohne Platzhalter), und enthält Rekursiv eine 1, werden mehrere Übereinstimmungen gefunden, wenn der angegebene Dateiname in mehreren Ordnern vorkommt.

OrdnerEinbeziehen?

Wenn dieser Parameter weggelassen wird oder leer ist, wird standardmäßig 0 (nur Dateien werden abgerufen) verwendet. Ansonsten können Sie eine der folgenden Ziffern angeben:

Rekursiv?

Wenn dieser Parameter weggelassen wird oder leer ist, wird standardmäßig 0 (Unterordner werden nicht rekursiv durchwandert) verwendet. Ansonsten können Sie eine der folgenden Ziffern angeben:

Sondervariablen innerhalb einer Datei-Schleife

Die folgenden Variablen können innerhalb einer Datei-Schleife verwendet werden. Wenn eine innere Datei-Schleife von einer äußeren Datei-Schleife umschlossen ist, hat die Datei der innersten Schleife Vorrang:

Variable Beschreibung
A_LoopFileName Der aktuell abgerufene Name der Datei oder des Ordners (ohne Pfad).
A_LoopFileExt Die Dateiendung (z. B. TXT, DOC oder EXE). Der Punkt (.) ist nicht enthalten.
A_LoopFileFullPath
A_LoopFilePath

Der aktuell abgerufene Pfad und Name der Datei oder des Ordners. Enthält DateiMuster einen relativen anstelle eines absoluten Pfades, wird der Pfad in dieser Variable auch relativ sein. Wenn ein 8.3-kurzer Ordnername in DateiMuster angegeben ist, wird er in dieser Variable auch kurz sein (siehe den nächsten Punkt, wie die lange Version ermittelt werden kann).

A_LoopFilePath steht in [v1.1.28+] als Alternative für A_LoopFileFullPath zur Verfügung, weil A_LoopFileFullPath eine Fehlbenennung ist.

A_LoopFileLongPath

Diese Variable unterscheidet sich von A_LoopFileFullPath wie folgt: 1) Sie enthält immer den absoluten/kompletten Pfad der Datei, auch dann, wenn DateiMuster einen relativen Pfad enthält; 2) 8.3-kurze Ordnernamen in DateiMuster werden in ihren langen Namen umgewandelt; 3) Die Zeichen in DateiMuster werden an die Groß- und Kleinschreibung angepasst, wie sie aktuell im Dateisystem gilt. Diese Variable ist für Dateinamen nützlich -- z. B. solche, die als Befehlszeilenparameter an das Skript übergeben werden -- die in ihren exakten Pfadnamen umgewandelt werden sollen, wie sie vom Explorer angezeigt werden.

A_LoopFileShortPath

Der aktuell abgerufene 8.3-kurze Pfad und Name der Datei oder des Ordners. Zum Beispiel: C:\MEINED~1\ADRESS~1.TXT. Enthält DateiMuster einen relativen anstelle eines absoluten Pfades, wird der Pfad in dieser Variable auch relativ sein.

Das folgende Beispiel zeigt, was DateiMuster enthalten muss, um den kompletten 8.3-Pfad und -Name einer Datei oder eines Ordners abzurufen:

Loop, C:\Meine Dokumente\Adressenliste.txt
    KurzerPfadname := A_LoopFileShortPath

Hinweis: Diese Variable wird leer sein, wenn die Datei keinen kurzen Namen hat. Dies könnte beispielsweise passieren, wenn NtfsDisable8dot3NameCreation in der Registry angegeben ist. Sie wird auch leer sein, wenn DateiMuster einen relativen Pfad enthält und der Schleifenkörper SetWorkingDir verwendet, um von dem eigentlichen Arbeitsverzeichnis der Schleife wegzuschalten.

A_LoopFileShortName Der 8.3-kurze Name oder alternative Name der Datei. Hat die Datei so einen Namen nicht (weil der lange Name kürzer ist als der 8.3-Name, oder vielleicht, weil die Kurznamengenerierung auf einem NTFS-Dateisystem deaktiviert ist), wird A_LoopFileName stattdessen abgerufen.
A_LoopFileDir Der Pfad des Verzeichnisses, in dem sich A_LoopFileName befindet. Enthält DateiMuster einen relativen anstelle eines absoluten Pfades, wird der Pfad in dieser Variable auch relativ sein. Das Root-Verzeichnis endet nicht mit einem umgekehrten Schrägstrich. Zum Beispiel: C:
A_LoopFileTimeModified Der Zeitpunkt, wann die Datei modifiziert wurde. YYYYMMDDHH24MISS-Format.
A_LoopFileTimeCreated Der Zeitpunkt, wann die Datei erstellt wurde. YYYYMMDDHH24MISS-Format.
A_LoopFileTimeAccessed Der Zeitpunkt, wann auf die Datei zugegriffen wurde. YYYYMMDDHH24MISS-Format.
A_LoopFileAttrib Die Attribute der aktuell abgerufenen Datei.
A_LoopFileSize Die Größe in Bytes der aktuell abgerufenen Datei. Dateien größer als 4 Gigabyte werden ebenfalls unterstützt.
A_LoopFileSizeKB Die Größe in Kilobytes der aktuell abgerufenen Datei, abgerundet auf den nächsten Integer.
A_LoopFileSizeMB Die Größe in Megabytes der aktuell abgerufenen Datei, abgerundet auf den nächsten Integer.

Bemerkungen

Eine Datei-Schleife ist nützlich, um mehrere Dateien und/oder Ordner einzeln abzuarbeiten.

Alle übereinstimmenden Dateien werden abgerufen, einschließlich versteckter Dateien. Aber Betriebssystem-Features wie der DIR-Befehl ignorieren versteckte Dateien. Um versteckte, systemspezifische und/oder schreibgeschützte Dateien innerhalb einer Schleife zu überspringen, können Sie zum Beispiel Folgendes innerhalb der Schleife verwenden:

if A_LoopFileAttrib contains H,R,S  ; Überspringt jede Datei, die H (versteckt), R (schreibgeschützt) oder S (systemspezifisch) ist. Hinweis: Keine Leerzeichen in "H,R,S".
    continue  ; Überspringt diese Datei und geht zur nächsten über.

Um bei einer rekursiven Suche relative statt absolute Pfade von Dateien abzurufen, ist es erforderlich, SetWorkingDir zu verwenden, um den Basisordner für die nachfolgende Schleife zu bestimmen, und dann die Schleife ohne Pfad anzugeben (z. B. Loop, *.*, 0, 1). Dies hat zur Folge, dass A_LoopFileFullPath einen Dateipfad enthalten wird, der relativ zum Basisordner ist.

Eine Datei-Schleife kann sich selbst unterbrechen, wenn sie Dateien oder Ordner innerhalb ihres eigenen Bereichs erstellt oder umbenennt. Wenn sie Dateien beispielsweise via FileMove oder auf eine andere Art umbenennen würde, könnten solche Dateien zweimal gefunden werden: einmal mit ihrem alten Namen und nochmals mit ihrem neuen Namen. Um das zu umgehen, erstellen Sie zuerst eine Liste von Dateien, bevor Sie sie umbenennen. Zum Beispiel:

DateiListe := ""
Loop, Files, *.jpg
    DateiListe .= A_LoopFileName "`n"
Loop, Parse, DateiListe, `n
    FileMove, %A_LoopField%, umbenannt_%A_LoopField%

Dateien in einem NTFS-Dateisystem werden wahrscheinlich immer in alphabetischer Reihenfolge abgerufen. Die Reihenfolge bei anderen Dateisystemen ist unbestimmt. Im Beispiel-Abschnitt unten wird gezeigt, wie der Sort-Befehl genutzt werden kann, um eine konsistente Reihenfolge zu gewährleisten.

Dateimuster länger als 259 Zeichen werden nur in den Unicode-Versionen von AutoHotkey [v1.1.31+] unterstützt, und auch nur, wenn mindestens eine der folgenden Bedingungen erfüllt ist:

In allen anderen Fällen werden Dateimuster länger als 259 Zeichen keine Dateien oder Ordner finden. Diese Limitierung gilt sowohl für DateiMuster als auch für alle temporären Muster, die beim rekursiven Durchwandern eines Unterordners verwendet werden. Die kombinierte Länge von Verzeichnis und Dateiname jeder Datei kann in [v1.1.31+] jedoch 259 Zeichen überschreiten; in älteren Versionen werden solche Dateien einfach übersprungen, als ob sie nicht existieren würden.

Auf der Loop-Seite finden Sie Informationen zu Blöcken, Break, Continue und A_Index (sie können in jeder Schleifenvariante verwendet werden).

Loop, Break, Continue, Blöcke, SplitPath, FileSetAttrib, FileSetTime

Beispiele

Meldet den vollständigen Pfad jeder Textdatei, die sich in einem Verzeichnis und in dessen Unterverzeichnissen befindet.

Loop Files, %A_ProgramFiles%\*.txt, R  ; Unterordner rekursiv durchwandern.
{
    MsgBox, 4, , Dateiname = %A_LoopFileFullPath%`n`nWeiter?
    IfMsgBox, No
        break
}

Berechnet die Größe eines Ordners mitsamt den Dateien in seinen Unterordnern.

SetBatchLines, -1  ; Führt die Operation mit maximaler Geschwindigkeit aus.
OrdnerGrößeKB := 0
FileSelectFolder, WelcherOrdner  ; Fordert den Benutzer auf, einen Ordner auszuwählen.
Loop, Files, %WelcherOrdner%\*.*, R
    OrdnerGrößeKB += A_LoopFileSizeKB
MsgBox Der Ordner %WelcherOrdner% hat eine Größe von %OrdnerGrößeKB% KB.

Ruft Dateinamen ab, sortiert nach Name (siehe nächstes Beispiel, wie nach Datum sortiert werden kann).

DateiListe := ""  ; Initialisiert sie als leere Variable.
Loop, C:\*.*
    DateiListe .= A_LoopFileName "`n"
Sort, DateiListe, R  ; Die R-Option sortiert in umgekehrter Richtung. Siehe Sort für weitere Optionen.
Loop, parse, DateiListe, `n
{
    if (A_LoopField = "")  ; Ignoriert das leere Element am Ende der Liste.
        continue
    MsgBox, 4,, Dateinummer %A_Index% ist %A_LoopField%.  Weiter?
    IfMsgBox, No
        break
}

Ruft Dateinamen ab, sortiert nach Änderungsdatum.

DateiListe := ""
Loop, Files, %A_MyDocuments%\Fotos\*.*, FD  ; Bezieht Dateien und Ordner mit ein
    DateiListe .= A_LoopFileTimeModified "`t" A_LoopFileName "`n"
Sort, DateiListe  ; Sortiert nach Datum.
Loop, Parse, DateiListe, `n
{
    if (A_LoopField = "")  ; Ignoriert das letzte LF-Zeichen (leere Element) am Ende der Liste.
        continue
    StringSplit, DateiElement, A_LoopField, %A_Tab%  ; Teilt es bei einem Tab-Zeichen in zwei Teile auf.
    MsgBox, 4,, Die nächste Datei ist (modifiziert am %DateiElement1%):`n%DateiElement2%`n`nWeiter?
    IfMsgBox, No
        break
}

Kopiert nur Quelldateien, die neuer sind als ihr Gegenstück, in das Ziel.

KopiereWennNeuer:
; Der Aufrufer hat die Variablen KopieQuelleMuster und KopieZiel für uns gesetzt.
Loop, Files, %KopieQuelleMuster%
{
    kopiere_es := false
    if not FileExist(KopieZiel "\" A_LoopFileName)  ; Kopiert immer die Zieldatei, wenn sie noch nicht existiert.
        kopiere_es := true
    else
    {
        FileGetTime, Zeitstempel, %KopieZiel%\%A_LoopFileName%
        EnvSub, Zeitstempel, %A_LoopFileTimeModified%, seconds  ; Subtrahiert die Zeit der Quelldatei mit der Zeit der Zieldatei.
        if (Zeitstempel < 0)  ; Quelldatei ist neuer als Zieldatei.
            kopiere_es := true
    }
    if kopiere_es
    {
        FileCopy, %A_LoopFileFullPath%, %KopieZiel%\%A_LoopFileName%, 1   ; Kopiert und überschreibt sie bei Bedarf
        if ErrorLevel
            MsgBox, "%A_LoopFileFullPath%" konnte nicht nach "%KopieZiel%\%A_LoopFileName%" kopiert werden.
    }
}
Return

Wandelt Dateinamen, die via Befehlszeilenparameter übergeben wurden, in lange Namen um, mit vollständigem Pfad und korrekter Groß-/Kleinschreibung, wie sie im Dateisystem vorkommen.

Loop %0%  ; Geht alle Dateien durch, die auf das Skript abgelegt wurden (oder als Parameter übergeben wurden).
{
    EingabePfad := %A_Index%  ; Ruft den nächsten Befehlszeilenparameter ab.
    Loop %EingabePfad%, 1
        LangerPfad := A_LoopFileLongPath
    MsgBox Der lange Pfadname mit korrekter Groß-/Kleinschreibung der Datei`n%EingabePfad%`nist:`n%LangerPfad%
}