检索文本文件中的行, 每次一行.
Loop Read InputFile , OutputFile
类型: 字符串
需要在循环中读取其内容的文本文件的名称, 如果未指定绝对路径, 则假定在 A_WorkingDir 中. 文件的行结束符可以是回车和换行符(`r`n), 也可以只是换行符(`n), 或只是回车(`r).
类型: 字符串
在循环期间保持打开的文件的名称, 如果未指定绝对路径, 则假定在 A_WorkingDir 中.
在循环的主体内, 使用 FileAppend 函数, 不带 Filename 参数(即省略它) 来追加到这个特殊的文件. 以这种方式追加到一个文件比使用 2 个参数模式的 FileAppend 执行地更好, 因为每次操作时不需要关闭文件和再重新打开. 如果需要的话, 记得在文本后加入换行符(`n) 或回车符和换行符(`r`n).
如果没有向文件写入任何内容, 文件就不会被打开. 如果循环执行零迭代或从未调用 FileAppend, 就会发生这种情况.
选项: 行末(EOL) 转换模式和输出文件编码取决于在 FileAppend 的首次调用中传递的选项(即省略 Filename 的首次调用). 随后的调用会忽略 Options 参数. 默认情况下不执行 EOL 转换; 也就是说, 除非存在 "`n"
选项, 否则换行符(`n) 将按原样写入.
标准输出(stdout): 指定 OutputFile 为星号(*) 可以把 FileAppend 写入的任何文本发送到标准输出(stdout). 这些文本可以重定向到文件, 指向另一个 EXE 的管道或被高级文本编辑器捕获, 然而发送到标准输出的文本不会出现在运行它的命令提示符中. 这可以通过以下方法解决 1) 使用 Ahk2Exe ConsoleApp 指令编译脚本, 或 2) 通过管道或重定向捕获脚本的输出. 有关详情, 请参阅 FileAppend.
当您想对包含在文本文件中的内容逐行进行操作时, 文件读取循环很有用. 在整个操作过程中, 文件是打开的, 以避免每次都要重新扫描以找到下一行.
内置变量 A_LoopReadLine 存在于任何文件读取循环中. 它包含当前行的内容, 不包括回车和标志行结束的换行符(`r`n). 如果一个内部的文件读取循环被一个外部的文件读取循环所包围, 那么最内部循环的文件行将优先.
读取长度为 65,534 个字符的行. 如果行的长度超过了这个长度, 其剩余的字符将在下一个循环迭代时被读取.
StrSplit 或解析循环通常用于文件读取循环中, 以解析从 InputFile 中获取的每一行的内容. 例如, 如果 InputFile 的每一行都是一系列以 tab 分隔的字段, 那么这些字段可以像这个例子一样单独检索:
Loop read, "C:\Database Export.txt" { Loop parse, A_LoopReadLine, A_Tab { MsgBox "Field number " A_Index " is " A_LoopField "." } }
要加载整个文件内容到变量中, 请使用 FileRead, 因为它比循环执行的更好(尤其对于大文件).
要同时打开多个文件, 请使用 FileOpen.
请参阅 Loop 了解关于区块, Break, Continue 和 A_Index 变量(其存在于各种类型的循环中) 的相关信息.
在不存在字节顺序标记时要控制如何解码文件, 请使用 FileEncoding.
循环的后面可以有一个可选的 Else 语句, 如果输入文件是空的或者找不到的话, 就会执行这个语句. 如果指定了 OutputFile, 上面描述的 FileAppend 的特殊模式也可以在 Else 语句的主体中使用. 如果没有 Else 语句, 如果找不到文件, 则抛出 OSError.
FileEncoding, FileOpen/File 对象, FileRead, FileAppend, Sort, Loop, Break, Continue, 区块, FileSetAttrib, FileSetTime
只有首个文件中包含单词 FAMILY 的那些行才会写入第二个文件中. 取消注释首行可以覆盖而不是追加到任何现有的文件中.
;FileDelete "C:\Docs\Family Addresses.txt" Loop read, "C:\Docs\Address List.txt", "C:\Docs\Family Addresses.txt" { if InStr(A_LoopReadLine, "family") FileAppend(A_LoopReadLine "`n") } else MsgBox "Address List.txt was completely empty or not found."
尝试从文本或 HTML 文件中提取所有 FTP 和 HTTP URL.
SourceFile := FileSelect(3,, "Pick a text or HTML file to analyze.") if SourceFile = "" return ; 此时将退出. SplitPath SourceFile,, &SourceFilePath,, &SourceFileNoExt DestFile := SourceFilePath "\" SourceFileNoExt " Extracted Links.txt" if FileExist(DestFile) { Result := MsgBox("Overwrite the existing links file? Press No to append to it.`n`nFILE: " DestFile,, 4) if Result = "Yes" FileDelete DestFile } LinkCount := 0 Loop read, SourceFile, DestFile { URLSearch(A_LoopReadLine) } MsgBox LinkCount ' links were found and written to "' DestFile '".' return URLSearch(URLSearchString) { ; 由于在一些 URL(网址) 中内嵌有其他的 URL, 所以用这种特殊的方法进行处理: ; 找到最左边的起始位置: URLStart := 0 ; 设置起始默认值. for URLPrefix in ["https://", "http://", "ftp://", "www."] { ThisPos := InStr(URLSearchString, URLPrefix) if !ThisPos ; 此前缀被取消资格. continue if !URLStart URLStart := ThisPos else ; URLStart 里面有一个有效的位置, 所以要和 ThisPos 比较一下. { if ThisPos && ThisPos < URLStart URLStart := ThisPos } } if !URLStart ; 在 URLSearchString 中不存在 URL. return ; 否则, 提取该 URL: URL := SubStr(URLSearchString, URLStart) ; 忽略开始/无效部分. Loop parse, URL, " `t<>" ; 找到首个空格, tab 或尖括号(如果有). { URL := A_LoopField break ; 即仅执行一次循环来获取首个 "片段". } ; 如果上面的循环因为没有找到结尾字符而导致迭代次数为零, ; 那么 URL 变量的内容保持不变. ; 如果 URL 以双引号结束, 那么移除它. 暂时使用 StringReplace, 不过注意 ; 双引号似乎可以合法存在于 URL 中, 所以这样做 ; 可能破坏它们: URLCleansed := StrReplace(URL, '"') FileAppend URLCleansed "`n" global LinkCount += 1 ; 看看当前行中是否含有其他 URL: CharactersToOmit := StrLen(URL) CharactersToOmit += URLStart URLSearchString := SubStr(URLSearchString, CharactersToOmit) ; 到自身的递归调用: URLSearch(URLSearchString) }