Loop Read

テキストファイルの行を1行ずつ取得します。

Loop Read InputFile , OutputFile

パラメータ

InputFile

型:文字列

絶対パスが指定されていない場合は、A_WorkingDirにあると仮定されます。ファイルの行末は、キャリッジリターンとラインフィード(`r`n)、ラインフィード(`n)だけ、またはキャリッジリターン(`r)だけであることができます。

OutputFile

型:文字列

(オプション)ループの間、開いておくファイルの名前。絶対パスが指定されていない場合は、A_WorkingDirにあると仮定される。

ループのボディ内で、FileAppend関数をFilenameパラメータなしで(つまり省略)使用し、この特別なファイルに追記します。この方法は、2パラメータモードのFileAppendを使用するよりも、操作のたびにファイルを閉じて開き直す必要がないため、より優れたパフォーマンスを発揮します。必要であれば、テキストの後にラインフィード(`n)またはキャリッジリターンとラインフィード(`r`n)を含めることを忘れないようにしてください。

何も書き込まれない場合は、ファイルは開かれません。This happens if the loop performs zero iterations or if it never calls FileAppend.

Options:行末(EOL)変換モードと出力ファイルのエンコーディングは、FileAppendのオープニングコール(Filenameを省略した最初のコール)でどのオプションが渡されるかに依存します。それ以降の呼び出しでは、Optionsパラメータは無視されます。つまり、"`n"オプションがない限り、改行文字(`n)はそのまま書き込まれます。

標準出力(stdout):OutputFileにアスタリスク(*)を指定すると、FileAppendで書き込んだテキストを標準出力(stdout)に出力します。このようなテキストは、ファイルにリダイレクトしたり、別のEXEにパイプしたり、おしゃれなテキストエディターでキャプチャしたりすることができます。ただし、stdoutに送られたテキストは、起動したコマンドプロンプトには表示されません。これは、1)Ahk2Exe ConsoleAppディレクティブでスクリプトをコンパイルする、または2)スクリプトの出力を他のコマンドやプログラムにパイプすることで回避することができます。詳細はFileAppendを参照のこと。

備考

ファイル読み込みループは、テキストファイルに含まれる行を1行ずつ操作したいときに便利です。次の行を探すために毎回再スキャンする必要がないように、操作中はファイルを開いたままにしておきます。

組み込み変数A_LoopReadLineは、任意のファイル読み込みループ内に存在します。行末を示すキャリッジリターンとラインフィード(`r`n)を除いた、現在の行の内容が含まれます。内側のファイル読み込みループが外側のファイル読み込みループに囲まれている場合、一番内側のループのファイル行が優先されます。

最大65,534文字までの行を読み取ることができます。行の長さがこれを超える場合は、次のループの繰り返しで残りの文字が読み取られます。

StrSplit構文解析ループは、ファイル読み込みループの中で、InputFileから取得した各行の内容を構文解析するためによく使われます。例えば、InputFileの行がそれぞれタブ区切りのフィールドの列である場合、この例のようにフィールドを個別に取得することができます:

Loop read, "C:\Database Export.txt"
{
    Loop parse, A_LoopReadLine, A_Tab
    {
        MsgBox "Field number " A_Index " is " A_LoopField "."
    }
}

ファイル全体を変数に読み込むには、ループよりもはるかに性能が良い(特に大きなファイルの場合)ので、FileReadを使用します。

複数のファイルを同時に開くには、FileOpenを使用します。

オプションで、オープンブレースを下ではなく同じラインに表示させるOTB(One True Brace)スタイルを採用することも可能です。事例:Loop Read InputFile, OutputFile {

ブロックBreakContinue、A_Index変数(どのタイプのループにも存在する)については、「Loop」をご覧ください。

バイトオーダーマークが存在しない場合のファイルのデコード方法を制御するには、FileEncodingを使用します。

ループの後には、入力ファイルが空であったり、見つからなかったりした場合に実行されるElse文がオプションで付いていることがあります。OutputFileが指定された場合、Else文の本体内では、上記FileAppendの特殊モードも使用することができます。Elseがない場合、ファイルが見つからなかった場合はOSErrorが投げられる。

FileEncodingFileOpen/FileオブジェクトFileReadFileAppendSortLoopBreakContinueブロックFileSetAttribFileSetTime

1つ目のファイルのうち、FAMILYという単語を含む行だけが、2つ目のファイルに書き込まれます。1行目のコメントを外すと、既存のファイルに追記するのではなく、上書きされます。

;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."

テキストファイルから最終行を取得する。

Loop read, "C:\Log File.txt"
    last_line := A_LoopReadLine  ; ループ終了時、最終行を保持します。

テキストファイルまたは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  ; No URLs exist in URLSearchString.
        return

    ; そうでない場合は、このURLを抽出します:
    URL := SubStr(URLSearchString, URLStart)  ; 先頭/関係ない部分を省略します。
    Loop parse, URL, " `t<>"  ; 最初のスペース、タブ、角括弧(もしあれば)を見つける。
    {
        URL := A_LoopField
        break  ; つまり、最初の "フィールド"を取得するために1回だけループを反復します。
    }
    ; もし、上記のループが、終了文字が見つからなかったために、繰り返し回数が0回だった場合、
    ; URL varの中身はそのままにしておく。

    ; URLの末尾がダブルクォートで終わっている場合は、それを削除する。今のところ、StrReplaceが使用されていますが
    ; 二重引用符はURLの中に合法的に存在できるようなので、この
    ; 破損する可能性があります:
    URLCleansed := StrReplace(URL, '"')
    FileAppend URLCleansed "`n"
    global LinkCount += 1

    ; この行の中に他のURLがあるかどうかを確認する:
    CharactersToOmit := StrLen(URL)
    CharactersToOmit += URLStart
    URLSearchString := SubStr(URLSearchString, CharactersToOmit)
    
    ; selfを再帰的に呼び出す:
    URLSearch(URLSearchString)
}