Loop (files & folders)

Retrieves the specified files or folders, one at a time.

New Syntax [v1.1.21+]

Loop, Files, FilePattern , Mode

Parameters

Files

The literal word Files (case-insensitive). This cannot be a variable or expression.

FilePattern

The name of a single file or folder, or a wildcard pattern such as C:\Temp\*.tmp. FilePattern is assumed to be in A_WorkingDir if an absolute path isn't specified.

Both asterisks and question marks are supported as wildcards. A match occurs when the pattern appears in either the file's long/normal name or its 8.3 short name.

If this parameter is a single file or folder (i.e. no wildcards) and Mode includes R, more than one match will be found if the specified file name appears in more than one of the folders being searched.

Patterns longer than 259 characters may fail to find any files due to system limitations (MAX_PATH). This limit can be bypassed by using the \\?\ long path prefix, with some stipulations.

Mode

If blank or omitted, only files are included and subdirectories are not recursed into. Otherwise, specify one or more of the following letters:

Old Syntax

Deprecated: This syntax is not recommended for use in new scripts. Use the new syntax described above instead.

Loop, FilePattern , IncludeFolders, Recurse

Parameters

FilePattern

The name of a single file or folder, or a wildcard pattern such as C:\Temp\*.tmp. FilePattern is assumed to be in %A_WorkingDir% if an absolute path isn't specified.

Both asterisks and question marks are supported as wildcards. A match occurs when the pattern appears in either the file's long/normal name or its 8.3 short name.

If this parameter is a single file or folder (i.e. no wildcards) and Recurse is set to 1, more than one match will be found if the specified file name appears in more than one of the folders being searched.

IncludeFolders

If blank or omitted, it defaults to 0. Otherwise, specify one of the following digits:

Recurse

If blank or omitted, it defaults to 0. Otherwise, specify one of the following digits:

Special Variables Available Inside a File Loop

The following variables exist within any file loop. If an inner file loop is enclosed by an outer file loop, the innermost loop's file will take precedence:

Variable Description
A_LoopFileName The name of the file or folder currently retrieved (without the path).
A_LoopFileExt The file's extension (e.g. TXT, DOC, or EXE). The period (.) is not included.
A_LoopFileFullPath
A_LoopFilePath

The path and name of the file/folder currently retrieved. If FilePattern contains a relative path rather than an absolute path, the path here will also be relative. In addition, any short (8.3) folder names in FilePattern will still be short (see next item to get the long version).

A_LoopFilePath is available in [v1.1.28+] as an alias of A_LoopFileFullPath, which is a misnomer.

A_LoopFileLongPath

This is different than A_LoopFileFullPath in the following ways: 1) It always contains the absolute/complete path of the file even if FilePattern contains a relative path; 2) Any short (8.3) folder names in FilePattern itself are converted to their long names; 3) Characters in FilePattern are converted to uppercase or lowercase to match the case stored in the file system. This is useful for converting file names -- such as those passed into a script as command line parameters -- to their exact path names as shown by Explorer.

A_LoopFileShortPath

The 8.3 short path and name of the file/folder currently retrieved. For example: C:\MYDOCU~1\ADDRES~1.txt. If FilePattern contains a relative path rather than an absolute path, the path here will also be relative.

To retrieve the complete 8.3 path and name for a single file or folder, follow this example:

Loop, C:\My Documents\Address List.txt
    ShortPathName := A_LoopFileShortPath

Note: This variable will be blank if the file does not have a short name, which can happen on systems where NtfsDisable8dot3NameCreation has been set in the registry. It will also be blank if FilePattern contains a relative path and the body of the loop uses SetWorkingDir to switch away from the working directory in effect for the loop itself.

A_LoopFileShortName The 8.3 short name or alternate name of the file. If the file doesn't have one (due to the long name being shorter than 8.3 or perhaps because short-name generation is disabled on an NTFS file system), A_LoopFileName will be retrieved instead.
A_LoopFileDir The path of the directory in which A_LoopFileName resides. If FilePattern contains a relative path rather than an absolute path, the path here will also be relative. A root directory will not contain a trailing backslash. For example: C:
A_LoopFileTimeModified The time the file was last modified. Format YYYYMMDDHH24MISS.
A_LoopFileTimeCreated The time the file was created. Format YYYYMMDDHH24MISS.
A_LoopFileTimeAccessed The time the file was last accessed. Format YYYYMMDDHH24MISS.
A_LoopFileAttrib The attributes of the file currently retrieved.
A_LoopFileSize The size in bytes of the file currently retrieved. Files larger than 4 gigabytes are also supported.
A_LoopFileSizeKB The size in Kbytes of the file currently retrieved, rounded down to the nearest integer.
A_LoopFileSizeMB The size in Mbytes of the file currently retrieved, rounded down to the nearest integer.

Remarks

A file loop is useful when you want to operate on a collection of files and/or folders, one at a time.

All matching files are retrieved, including hidden files. By contrast, OS features such as the DIR command omit hidden files by default. To avoid processing hidden, system, and/or read-only files, use something like the following inside the loop:

if A_LoopFileAttrib contains H,R,S  ; Skip any file that is either H (Hidden), R (Read-only), or S (System). Note: No spaces in "H,R,S".
    continue  ; Skip this file and move on to the next one.

To retrieve files' relative paths instead of absolute paths during a recursive search, use SetWorkingDir to change to the base folder prior to the loop, and then omit the path from the loop (e.g. Loop, *.*, 0, 1). That will cause A_LoopFileFullPath to contain the file's path relative to the base folder.

A file loop can disrupt itself if it creates or renames files or folders within its own purview. For example, if it renames files via FileMove or other means, each such file might be found twice: once as its old name and again as its new name. To work around this, rename the files only after creating a list of them. For example:

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

Files in an NTFS file system are probably always retrieved in alphabetical order. Files in other file systems are retrieved in no particular order. To ensure a particular ordering, use the Sort command as shown in the Examples section below.

File patterns longer than 259 characters are supported only by Unicode versions of AutoHotkey [v1.1.31+], and only when at least one of the following is true:

In all other cases, file patterns longer than 259 characters will not find any files or folders. This limit applies both to FilePattern and any temporary pattern used during recursion into a subfolder. However, the combined length of each file's directory and filename can exceed 259 characters in [v1.1.31+]; on earlier versions such files are skipped over as though they do not exist.

See Loop for information about Blocks, Break, Continue, and the A_Index variable (which exists in every type of loop).

The commands FileGetAttrib, FileGetSize, FileGetTime, FileGetVersion, FileSetAttrib, and FileSetTime can be used in a file loop without their Filename/FilePattern parameter.

Loop, Break, Continue, Blocks, SplitPath, FileSetAttrib, FileSetTime

Examples

Reports the full path of each text file located in a directory and in its subdirectories.

Loop Files, %A_ProgramFiles%\*.txt, R  ; Recurse into subfolders.
{
    MsgBox, 4, , Filename = %A_LoopFileFullPath%`n`nContinue?
    IfMsgBox, No
        break
}

Calculates the size of a folder, including the files in all its subfolders.

SetBatchLines, -1  ; Make the operation run at maximum speed.
FolderSizeKB := 0
FileSelectFolder, WhichFolder  ; Ask the user to pick a folder.
Loop, Files, %WhichFolder%\*.*, R
    FolderSizeKB += A_LoopFileSizeKB
MsgBox Size of %WhichFolder% is %FolderSizeKB% KB.

Retrieves file names sorted by name (see next example to sort by date).

FileList := ""  ; Initialize to be blank.
Loop, C:\*.*
    FileList .= A_LoopFileName "`n"
Sort, FileList, R  ; The R option sorts in reverse order. See Sort for other options.
Loop, parse, FileList, `n
{
    if (A_LoopField = "")  ; Ignore the blank item at the end of the list.
        continue
    MsgBox, 4,, File number %A_Index% is %A_LoopField%.  Continue?
    IfMsgBox, No
        break
}

Retrieves file names sorted by modification date.

FileList := ""
Loop, Files, %A_MyDocuments%\Photos\*.*, FD  ; Include Files and Directories
    FileList .= A_LoopFileTimeModified "`t" A_LoopFileName "`n"
Sort, FileList  ; Sort by date.
Loop, Parse, FileList, `n
{
    if (A_LoopField = "")  ; Omit the last linefeed (blank item) at the end of the list.
        continue
    StringSplit, FileItem, A_LoopField, %A_Tab%  ; Split into two parts at the tab char.
    MsgBox, 4,, The next file (modified at %FileItem1%) is:`n%FileItem2%`n`nContinue?
    IfMsgBox, No
        break
}

Copies only the source files that are newer than their counterparts in the destination.

CopyIfNewer:
; Caller has set the variables CopySourcePattern and CopyDest for us.
Loop, Files, %CopySourcePattern%
{
    copy_it := false
    if not FileExist(CopyDest "\" A_LoopFileName)  ; Always copy if target file doesn't yet exist.
        copy_it := true
    else
    {
        FileGetTime, time, %CopyDest%\%A_LoopFileName%
        EnvSub, time, %A_LoopFileTimeModified%, seconds  ; Subtract the source file's time from the destination's.
        if (time < 0)  ; Source file is newer than destination file.
            copy_it := true
    }
    if copy_it
    {
        FileCopy, %A_LoopFileFullPath%, %CopyDest%\%A_LoopFileName%, 1   ; Copy with overwrite=yes
        if ErrorLevel
            MsgBox, Could not copy "%A_LoopFileFullPath%" to "%CopyDest%\%A_LoopFileName%".
    }
}
Return

Converts filenames passed in via command-line parameters to long names, complete path, and correct uppercase/lowercase characters as stored in the file system.

Loop %0%  ; For each file dropped onto the script (or passed as a parameter).
{
    GivenPath := %A_Index%  ; Retrieve the next command line parameter.
    Loop %GivenPath%, 1
        LongPath := A_LoopFileLongPath
    MsgBox The case-corrected long path name of file`n%GivenPath%`nis:`n%LongPath%
}