检索指定的文件或文件夹, 每次一个.
Loop Files FilePattern , Mode
类型: 字符串
单个文件或文件夹的名称, 或者通配符模式, 如 "C:\Temp\*.tmp". 如果未指定绝对路径, 则假定 FilePattern 在 A_WorkingDir 中.
支持星号和问号作为通配符使用. 当模式出现在文件的长/普通名称或其 8.3 短名称时出现匹配.
如果此参数为单个文件或文件夹(即不含通配符) 且 Mode 包含 R, 同时指定的文件名出现在多个被搜索的文件夹中, 那么将找到多个匹配.
由于系统限制(MAX_PATH), 超过 259 个字符的模式可能无法找到任何文件. 这个限制可以通过使用 \\?\ 长路径前缀绕过, 但有一些条件.
\\?\
如果为空或省略, 则只包括文件且不递归子文件夹. 否则, 指定一个或多个下列字母:
下列变量存在于任何文件循环中. 如果一个内层文件循环包含在一个外层文件循环中, 那么最内层循环的文件将具有优先权:
当前检索文件/文件夹的 8.3 短路径和名称. 例如: C:\MYDOCU~1\ADDRES~1.txt. 如果 FilePattern 包含相对路径而不是绝对路径, 这里的路径也将是相对路径.
要检索单个文件或文件夹的完整的 8.3 路径和名称, 像这个例子那样在 FilePattern 中指定其名称:
Loop Files, "C:\My Documents\Address List.txt" ShortPathName := A_LoopFileShortPath
注意: 如果文件没有短文件名, 这个变量将为空, 这可能发生在注册表中设置了 NtfsDisable8dot3NameCreation 的系统中. 如果 FilePattern 包含一个相对路径并且循环的主体使用 SetWorkingDir 从循环本身的工作目录中切换出来, 那么这个变量也将是空白的.
当你想对一系列文件和/或文件夹进行操作时, 文件循环非常有用, 每次一个.
所有匹配的文件都会被检索出来, 包括隐藏的文件. 相比之下, 操作系统的功能, 如 DIR 命令, 默认情况下会省略隐藏文件. 为了避免处理隐藏的, 系统的, 和/或只读的文件, 在循环中使用类似下面的方法:
if A_LoopFileAttrib ~= "[HRS]" ; 跳过任何具有 H(隐藏), R(只读) 或 S(系统). 请参阅 ~= 运算符. continue ; 跳过这个文件并继续下一个文件.
在递归搜索过程中, 要检索文件的相对路径而不是绝对路径, 在循环之前使用 SetWorkingDir 改变基文件夹, 然后在循环中省略路径(例如 Loop Files, "*.*", "R"). 这将导致 A_LoopFilePath 包含相对于基文件夹的文件路径.
Loop Files, "*.*", "R"
如果一个文件循环在它自己的权限范围内创建或重命名文件或文件夹, 它可能会自乱阵脚. 例如, 如果通过 FileMove 或其他方式重命名文件, 每个这样的文件可能会被发现两次: 一次是旧名, 另一次是新名. 为了解决这个问题, 只有在创建文件列表后才重命名这些文件. 例如:
FileList := "" Loop Files, "*.jpg" FileList .= A_LoopFileName "`n" Loop Parse, FileList, "`n" FileMove A_LoopField, "renamed_" A_LoopField
在 NTFS 文件系统中的文件可能总是按字母顺序来获取. 在其他文件系统中的文件则没有特殊的获取顺序. 要使用特殊的获取顺序, 使用 Sort 命令, 如同下文示例部分演示的那样.
支持超过 259 个字符的文件模式, 仅在满足至少一个以下情况时有效:
在所有其他情况下, 超过 259 个字符的文件模式将不会找到任何文件或文件夹. 这个限制既适用于 FilePattern, 也适用于递归到子文件夹时使用的任何临时模式.
请参阅 Loop 了解关于区块, Break, Continue 和 A_Index 变量(其存在于各种类型的循环中) 的相关信息.
循环后面可以有一个可选的 Else 语句, 如果没有找到匹配的文件或目录(即循环的迭代次数为零), 则执行 Else 语句.
Loop, Break, Continue, 区块, SplitPath, FileSetAttrib, FileSetTime
报告位于目录及其子目录中的每个文本文件的完整路径.
Loop Files, A_ProgramFiles "\*.txt", "R" ; 递归子文件夹. { Result := MsgBox("Filename = " A_LoopFilePath "`n`nContinue?",, "y/n") if Result = "No" break }
计算文件夹的大小, 包括其所有子文件夹中的文件.
FolderSizeKB := 0 WhichFolder := DirSelect() ; 让用户选取文件夹. Loop Files, WhichFolder "\*.*", "R" FolderSizeKB += A_LoopFileSizeKB MsgBox "Size of " WhichFolder " is " FolderSizeKB " KB."
获取根据名称排序的文件名(要以日期排序请参阅下一个例子).
FileList := "" ; 初始化为空. Loop Files, "C:\*.*" FileList .= A_LoopFileName "`n" FileList := Sort(FileList, "R") ; R 选项逆序排列. 有关其他选项, 请参阅 Sort. Loop Parse, FileList, "`n" { if A_LoopField = "" ; 忽略列表末尾的空项. continue Result := MsgBox("File number " A_Index " is " A_LoopField ". Continue?",, "y/n") if Result = "No" break }
获取根据修改日期排序的文件名.
FileList := "" Loop Files, A_MyDocuments "\Photos\*.*", "FD" ; 包含文件和子目录 FileList .= A_LoopFileTimeModified "`t" A_LoopFileName "`n" FileList := Sort(FileList) ; 根据日期排序. Loop Parse, FileList, "`n" { if A_LoopField = "" ; 忽略列表末尾的最后一个换行符(空项). continue FileItem := StrSplit(A_LoopField, A_Tab) ; 用 tab 作为分隔符将其分为两部分. Result := MsgBox("The next file (modified at " FileItem[1] ") is:`n" FileItem[2] "`n`nContinue?",, "y/n") if Result = "No" break }
仅复制比目标位置中的对应文件更新的源文件.
CopyIfNewer: ; 调用者已经为我们赋值了变量 CopySourcePattern 和 CopyDest. Loop Files, CopySourcePattern { copy_it := false if !FileExist(CopyDest "\" A_LoopFileName) ; 如果目标文件还不存在, 那么总是复制. copy_it := true else { time := FileGetTime(CopyDest "\" A_LoopFileName) time := DateDiff(A_Now, A_LoopFileTimeModified, "Seconds") ; 从目的时间中减去源文件的时间. if time < 0 ; 源文件比目的文件新. copy_it := true } if copy_it { try FileCopy A_LoopFilePath, CopyDest "\" A_LoopFileName, 1 ; 以覆盖形式复制 overwrite=yes catch MsgBox 'Could not copy "' A_LoopFilePath '" to "' CopyDest '\' A_LoopFileName '".' } } Return
把通过命令行参数传递的文件名转换为长名称, 完整路径和在文件系统中存储的正确的大写/小写字符形式.
for GivenPath in A_Args ; 对于每一个参数(或拖放到脚本中的文件): { Loop Files, GivenPath, "FD" ; 包括文件和目录. LongPath := A_LoopFilePath MsgBox "The case-corrected long path name of file`n" GivenPath "`nis:`n" LongPath }