Loop Files

指定したファイルやフォルダを1つずつ取得します。

Loop Files FilePattern , Mode

パラメータ

FilePattern

型:文字列

単一のファイルまたはフォルダの名前、または"C:\Temp\*.tmp"のようなワイルドカードパターンです。FilePatternは、絶対パスが指定されない場合、A_WorkingDirにあるとみなされます。

ワイルドカードとして、アスタリスクとクエスチョンマークの両方がサポートされています。ファイルのロング/ノーマル名または8.3ショート名のいずれかにパターンがある場合、一致することになります。

このパラメータが単一のファイルまたはフォルダ(すなわちワイルドカードなし)で、ModeにRが含まれる場合、指定されたファイル名が検索対象の複数のフォルダに現れると、複数の一致が検出されます。

259文字以上のパターンは、システムの制限(MAX_PATH)により、ファイルの検索に失敗する場合があります。この制限は、いくつかの条件を満たした上で、\\?\ ロングパスプリフィクスを使用することで回避することができます。

Mode

型:文字列

空白または省略された場合、ファイルのみが含まれ、サブディレクトリは再帰されません。それ以外の場合は、以下の文字を1つ以上指定してください:

ファイルループ内で使用できる特殊な変数

ファイルループ内には、以下の変数が存在します。内側のファイルループが外側のファイルループで囲まれている場合、最も内側のループのファイルが優先されます:

変数 説明
A_LoopFileName 現在取得されているファイルまたはフォルダの名前(パスなし)です。
A_LoopFileExt ファイルの拡張子(例:TXT、DOC、EXE)。ピリオド(.)は含まれません。
A_LoopFilePath 現在取得しているファイル/フォルダのパスと名前。FilePatternに絶対パスではなく相対パスが含まれている場合、ここでのパスも相対パスとなります。また、FilePatternで短い(8.3)フォルダ名は、そのまま短くなります(長いバージョンを取得するには、次の項目を参照してください)。
A_LoopFileFullPath A_LoopFilePathとは、以下の点で異なります:1)FilePatternに相対パスが含まれていても、常にファイルの絶対パス/完全パスを含む。 2)FilePattern自体に含まれる短い(8.3)フォルダ名は、その長い名前に変換される。 3)FilePattern内の文字は、ファイルシステムに保存されているケースに合わせて大文字または小文字に変換される。コマンドラインパラメーターとしてスクリプトに渡されたファイル名などを、エクスプローラで表示される正確なパス名に変換するのに便利です。
A_LoopFileShortPath

現在検索しているファイル/フォルダの 8.3 ショートパスと名前。事例:C:\MYDOCU~1\ADDRES~1.txt。FilePatternに絶対パスではなく相対パスが含まれている場合、ここでのパスも相対パスとなります。

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

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

注意:NtfsDisable8dot3NameCreationがレジストリに設定されているシステムで起こりうることですが、ファイルに短い名前がない場合、この変数は空白となります。また、FilePatternに相対パスが含まれていて、ループの本体がSetWorkingDirを使用してループ自体の有効な作業ディレクトリから切り離す場合は空白となります。

A_LoopFileShortName 8.3ショートネーム、またはファイルの代替名。ファイルに名前がない場合(長い名前が8.3より短いか、NTFSファイルシステムで短縮名の生成が無効になっているため)、代わりにA_LoopFileNameが取得されます。
A_LoopFileDir A_LoopFileNameが存在するディレクトリのパス。FilePatternに絶対パスではなく相対パスが含まれている場合、ここでのパスも相対パスとなります。ルートディレクトリには、末尾のバックスラッシュは含まれません。事例:C:
A_LoopFileTimeModified ファイルが最後に更新された時刻。Format YYYYMMDDHH24MISS.
A_LoopFileTimeCreated ファイルが作成された時刻です。Format YYYYMMDDHH24MISS.
A_LoopFileTimeAccessed ファイルが最後にアクセスされた時刻です。Format YYYYMMDDHH24MISS.
A_LoopFileAttrib 現在検索しているファイルの属性
A_LoopFileSize 現在取得中のファイルのサイズ(バイト数)です。4ギガバイトを超えるファイルにも対応しています。
A_LoopFileSizeKB 現在取得中のファイルのサイズ(Kbyte)を、最も近い整数に切り捨てたもの。
A_LoopFileSizeMB 現在取得中のファイルのサイズ(Mbyte)。小数点以下は切り捨てます。

備考

ファイルループは、ファイルやフォルダの集合体を一度に操作する場合に便利です。

隠しファイルを含め、一致するすべてのファイルを取得します。これに対し、DIRコマンドなどのOSの機能は、デフォルトで隠しファイルを省略します。隠しファイル、システムファイル、読み取り専用ファイルの処理を避けるために、ループ内で以下のように使用します:

if A_LoopFileAttrib ~= "[HRS]"  ; H(Hidden)、R(Read-only)、S(System)のいずれかに該当するファイルをスキップします。~=演算子を参照。
    continue  ; このファイルをスキップして、次のファイルに移る。

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 Files, "*.*", "R"). これにより、A_LoopFilePathには、ベースフォルダからの相対的なファイルのパスが含まれることになります。

ファイルループは、自分の権限でファイルやフォルダを作成したり、名前を変更したりすると、それ自体が混乱することがあります。例えば、FileMoveなどでファイル名を変更した場合、そのようなファイルが2回見つかる可能性があります:旧名称ならば、新名称とします。これを回避するには、ファイルのリストを作成した後にのみファイル名を変更します。事例:

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

NTFSファイルシステム内のファイルは、おそらく常にアルファベット順に検索されます。他のファイルシステムのファイルは、順不同で検索されます。特定の順序を確保するためには、以下の「例」のようにソート機能を使用します。

259文字より長いファイルパターンは、以下のうち少なくとも1つが成立している場合にのみサポートされます:

それ以外の場合、259文字より長いファイルパターンは、ファイルやフォルダーを見つけることができません。この制限は、FilePatternと、サブフォルダへの再帰中に使用される一時的なパターンの両方に適用されます。

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

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

ループの後にElse文が続くことがありますが、これは一致するファイルやディレクトリが見つからなかった場合に実行されます(つまり、ループの反復回数がゼロの場合)。

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

LoopBreakContinueブロックSplitPathFileSetAttribFileSetTime

ディレクトリとそのサブディレクトリにある各テキストファイルのフルパスを表示します。

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)  ; Sort by date.
Loop Parse, FileList, "`n"
{
    if A_LoopField = "" ; リスト末尾のラインフィード(空白項目)を省略します。
        continue
    FileItem := StrSplit(A_LoopField, A_Tab)  ; タブ文字で2つに分割します。
    Result := MsgBox("The next file (modified at " FileItem[1] ") is:`n" FileItem[2] "`n`nContinue?",, "y/n")
    if Result = "No"
        break
}

コピー先のファイルより新しいソースファイルのみをコピーします。この関数は、"A:\Scripts\*.ahk"のようなソースパターンと"B:\Script Backup"のような既存の保存先ディレクトリを指定して呼び出します。

CopyIfNewer(SourcePattern, Dest)
{
    Loop Files, SourcePattern
    {
        copy_it := false
        if !FileExist(Dest "\" A_LoopFileName)  ; 対象ファイルがまだ存在しない場合は常にコピーします。
            copy_it := true
        else
        {
            time := FileGetTime(Dest "\" A_LoopFileName)
            time := DateDiff(time, A_LoopFileTimeModified, "Seconds")  ; 送信元ファイルの時刻と送信先ファイルの時刻を引き算します。
            if time < 0  ; ソースファイルはデスティネーションファイルより新しい。
                copy_it := true
        }
        if copy_it
        {
            try
                FileCopy A_LoopFilePath, Dest "\" A_LoopFileName, 1   ; 上書きコピー(Yes)
            catch
                MsgBox 'Could not copy "' A_LoopFilePath '" to "' Dest '\' A_LoopFileName '".'
        }
    }
}

コマンドラインパラメーターで渡されたファイル名を、ファイルシステムに格納されているような長い名前、完全なパス、正しい大文字/小文字に変換します。

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
}