Loop (파일 내용 읽기)

텍스트 파일에서 한 번에 한 줄씩 열람합니다 (FileReadLine보다 수행성능이 좋습니다).

Loop, Read, InputFile [, OutputFile]

매개변수

Read

이 매개변수는 반드시 단어 READ이어야 합니다.

InputFile

그의 내용이 회돌이에 읽혀 질 텍스트 파일의 이름. 절대 경로가 지정되어 있지 않으면 %A_WorkingDir%에 있다고 간주됩니다. Windows와 Unix 형식을 지원합니다; 즉, 파일 줄은 캐리지 리턴과 라인피드로 (`r`n) 끝나거나 아니면 그냥 라인피드로 (`n) 끝날 수 있습니다.

OutputFile

(선택적) 회돌이를 하는 동안 열어 둘 파일의 이름. 절대 경로를 지정하지 않으면 %A_WorkingDir%에 있다고 간주됩니다.

회돌이 몸체 안에서 매개 변수 하나만 (씌여질 텍스트만) 가지고 FileAppend 명령어를 사용하면 이 특별한 파일에 추가할 수 있습니다. 이런 방식으로 파일에 추가하면 FileAppend를 매개변수 2 개와 함께 사용하는 것보다 더 수행성능이 좋습니다. 왜냐하면 파일을 각 연산마다 닫고 다시 열 필요가 없기 때문입니다. 잊지 말고 텍스트 끝에 라인피드를 (`n) 추가하십시오.

아무것도 씌여지지 않으면 파일은 열리지 않습니다. 이런 일은 Loop가 전혀 반복을 수행하지 않거나 FileAppend 명령어를 전혀 사용하지 않을 때 일어납니다.

이진 모드: 텍스트 모드가 아니라 이진 모드로 추가하려면, 파일 이름 앞에 별표를 배치하십시오. 이렇게 하면 각 라인피드 문자가 (`n) 윈도우즈의 표준 CR+LF가 아니라 단일 라인피드로 씌여집니다 (LF). 예를 들어: *C:\My Unix File.txt. 별표가 없더라도, FileAppend를 처음 사용할 때 Loop에서 캐리지 리턴과 라인피드를 쓰면 (`r`n) 이진 모드가 자동으로 켜집니다(?).

표준 출력 (stdout): 별표를 (*) OutputFile에 지정하면 FileAppend가 쓰는 모든 텍스트는 표준 출력으로 전송됩니다 (stdout). 그런 출력을 파일에 방향전환하거나, 또다른 EXE로 파이프 처리하거나, 또는 멋진 텍스트 편집기로 나포할 수는 있지만, 기동된 명령어 프롬프트에 스크립트가 나타나지 않습니다. 더 자세한 것은 FileAppend를 참조하십시오.

피신된 쉼표: 대부분의 다른 명령어의 마지막 매개변수와 다르게, OutputFile에서 쉼표는 반드시 피신시켜야 합니다 (`,).

논평

파일-읽기 회돌이는 텍스트 파일에 든 각 줄을 한 번에 하나씩 처리할 때 유용합니다. FileReadLine을 사용하는 것보다 더 수행성능이 좋습니다. 왜냐햐면: 1) 연산 기간동안 파일이 열린 상태로 있을 수 있습니다; 그리고 2) 그 파일은 요청된 줄 번호츨 찾기 위해 매번 다시 스캔할 필요가 없습니다.

내장 변수 A_LoopReadLine은 모든 파일-읽기 회돌이 안에 존재합니다. 안에 현재 줄의 내용이 담겨 있습니다. 줄 끝을 표식하는 캐리지 리턴과 라인피드는 제외되어 있습니다 (`r`n). 내부 파일-읽기 회돌이가 바깥 파일-읽기 회돌이로 둘러 싸여 있다면, 가장 안쪽 회돌이의 파일-줄이 우선 순위를 갖습니다.

줄 당 65,534 문자 길이까지 읽을 수 있습니다. 줄 길이가 이 제한을 초과하면, 나머지 문자들을 다음 회돌이 때 읽힙니다.

InputFile으로부터 열람된 각 줄의 내용을 분해하기 위해 StringSplit 또는 파싱 회돌이가 종종 사용됩니다. 예를 들어, InputFile의 각 줄이 탭으로-구분된 일련의 필드로 구성되어 있다면, 그 필드들은 다음 예제와 같이 개별적으로 열람할 수 있습니다:

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

전체 파일을 변수 안으로 적재하려면, FileRead를 사용하십시오. 왜냐하면 회돌이보다 수행성능이 (특히 방대한 파일에 대하여) 훨씬 더 좋기 때문입니다.

여러 파일을 동시에 열려면, 다음 예제에 보여주는 바와 같이 DllCall()를 사용하십시오.

Blocks, Break, Continue, 그리고 (모든 유형의 회돌이에 존재하는) A_Index 변수에 관한 정보는 Loop를 참조하십시오.

바이트 순서 표식이 없을 때 파일을 어떻게 디코드할지 제어하려면 FileEncoding을 사용하십시오.

관련 항목

FileEncoding, FileOpen/File Object, FileRead, FileReadLine, FileAppend, Sort, Loop, Break, Continue, Blocks, FileSetAttrib, FileSetTime

예제

; 예제 #1: 1st 파일에서 단어 FAMILY가 든 줄들만 2nd 파일에 씌여집니다.
; 기존의 파일에 추가하는게 아니라 덮어쓰려면 첫 줄을 주석 해제하십시오.
;FileDelete, C:\Docs\Family Addresses.txt

Loop, read, C:\Docs\Address List.txt, C:\Docs\Family Addresses.txt
{
    IfInString, A_LoopReadLine, family, FileAppend, %A_LoopReadLine%`n
}

 

; 예제 #2: 텍스트 파일로부터 마지막 줄을 열람합니다.
Loop, read, C:\Log File.txt
    last_line := A_LoopReadLine  ; 회돌이가 끝날 때, 여기에 그 마지막 줄을 보유합니다.

 

; 예제 #3: 다음 스크립트는 HTML이나 텍스트 파일로부터
; FTP와 HTTP의 URL을 모두 추출하려고 시도합니다:
FileSelectFile, SourceFile, 3,, Pick a text or HTML file to analyze.
if SourceFile =
    return  ; 이 경우 종료합니다.

SplitPath, SourceFile,, SourceFilePath,, SourceFileNoExt
DestFile = %SourceFilePath%\%SourceFileNoExt% Extracted Links.txt

IfExist, %DestFile%
{
    MsgBox, 4,, Overwrite the existing links file? Press No to append to it.`n`nFILE: %DestFile%
    IfMsgBox, Yes
        FileDelete, %DestFile%
}

LinkCount = 0
Loop, read, %SourceFile%, %DestFile%
{
    URLSearchString = %A_LoopReadLine%
    Gosub, URLSearch
}
MsgBox %LinkCount% links were found and written to "%DestFile%".
return


URLSearch:
; 다음과 같이 특별한 방식으로 처리됩니다. 왜냐하면 어떤 URL은 다른 URL을 자신 안에 내장하기 때문입니다:
StringGetPos, URLStart1, URLSearchString, http://
StringGetPos, URLStart2, URLSearchString, ftp://
StringGetPos, URLStart3, URLSearchString, www.

; 가장 왼쪽의 시작 지점을 찾습니다:
URLStart = %URLStart1%  ; 기본 시작 지점을 설정합니다.
Loop
{
    ; "URLStart%A_Index%"를 한 번만 결정하면
    ; (적어도 많은 변수가 있는 스크립트에서) 수행성능이 향상됩니다
    ArrayElement := URLStart%A_Index%
    if ArrayElement =  ; 의사-배열의 끝에 도달했습니다.
        break
    if ArrayElement = -1  ; 이 요소는 자격이 없습니다.
        continue
    if URLStart = -1
        URLStart = %ArrayElement%
    else ; URLStart는 안에 유효한 위치를 가지고 있습니다.. 그래서 그것을 ArrayElement와 비교합니다.
    {
        if ArrayElement <> -1
            if ArrayElement < %URLStart%
                URLStart = %ArrayElement%
    }
}

if URLStart = -1  ; URL이 URLSearchString에 존재하지 않습니다.
    return

; 그렇지 않으면, 이 URL을 추출합니다:
StringTrimLeft, URL, URLSearchString, %URLStart%  ; 시작/부적절 부분을 제거합니다.
Loop, parse, URL, %A_Tab%%A_Space%<>  ; (있다면) 첫 번째 스페이스, 탭, 또는 앵글 문자를 찾습니다.
{
    URL = %A_LoopField%
    break  ; 즉, 첫 번째 "필드"를 가져 오기 위해 오직 한 번만 회돌이를 수행합니다.
}
; 종료 문자가 발견되지 않아서 위의 회돌이에 반복이 없다면,
; URL 변수의 내용을 그대로 둡니다.

; URL이 겹따옴표로 끝나면, 겹따옴표를 제거합니다. 지금 당장은 StringReplace가 사용됩니다.
; 그러나 겹따옴표가 URL 안에 존재해도 유효한 것 같습니다.
; 그래서 제거하면 손상을 입힐 수도 있습니다:
StringReplace, URLCleansed, URL, ",, All
FileAppend, %URLCleansed%`n
LinkCount += 1

; 이 줄에 다른 URL들이 있는 알아 봅니다:
StringLen, CharactersToOmit, URL
CharactersToOmit += %URLStart%
StringTrimLeft, URLSearchString, URLSearchString, %CharactersToOmit%
Gosub, URLSearch  ; 자신에게 재귀 호출을 합니다.
return