방개
비밀번호를 잊어버리셨나요?

질문

A_TickCount와 loop, parse에서의 FileCreateDir에 대해서 질문드립니다.

    • 글자 크기

안녕하세요. 프날님 강의 보고 며칠전부터 오토핫키를 시작했습니다. 먼저 잘 정리된 강의 감사하단 말씀부터 드립니다.
질문드릴 것은 A_TickCount와 loop, parse에서의 FileCreateDir에 대해서입니다. 목적은 이미지 서치를 해서 다운로드 후 적절히 정리하는 매크로인데요, 아래와 같습니다.

 

먼저 Input.txt의 내용입니다.
https://weather.naver.com/air/09140104
https://weather.naver.com/today/09140104
https://weather.naver.com/video/09140104
##WeatherNHN
https://news.naver.com/main/main.nhn?mode=LSD&mid=shm&sid1=102
https://news.naver.com/main/main.nhn?mode=LSD&mid=shm&sid1=101
##newsNHN
https://sports.news.naver.com/kbaseball/index.nhn
https://sports.news.naver.com/kfootball/index.nhn
https://sports.news.naver.com/wbaseball/index.nhn
##sportsNHN


;;;;;;;;;;;;;코드 시작;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


#SingleInstance Force
#NoEnv
SetWorkingDir %A_ScriptDir%
SetBatchLines -1

FileRead, temp, Input.txt ;Input.txt 존재여부 확인
	if ErrorLevel = 1
	{
		MsgBox, 016, Error, Missing Input.txt!!!
		return
	}

Gui Add, Text, x29 y16 w246 h26 +Center, 테스트
Gui Add, Text, x30 y64 w122 h28 +0x200, Current
Gui Add, Text, x30 y100 w122 h28 +0x200, TxtRowCount
Gui Add, Edit, vCurrent x150 y64 w122 h28 +ReadOnly -VScroll, 1
Gui Add, Edit, vTxtRowCount x150 y100 w122 h28 -VScroll,
Gui Add, Button, gRun x100 y154 w106 h28, Run!(F4)
Gui Add, StatusBar, vstatRuntime +Right, Runtime:

Gui Show, w306 h250, test

	loop, read, Input.txt ;Gui TxtRowCount (vTxtRowCount)에 Input.txt가 몇줄인지 카운트해서 넘겨줌.
		{
		if A_LoopReadLine=
			continue
		TxtRows++
		}
	GuiControl, , TxtRowCount, %TxtRows%	

	Runtime_GUIUpdate: ;상태창에 처리에 걸린 적산시간 표시해주는 모듈.
		RunTime = 20000101000000 ;기본형
		RunTime += (A_TickCount - InitTime)/1000,Seconds ;a tickcount로 측정되는 현재시간(컴퓨터 작동시간)과 gRun이 시작되면서 계산되는 InitTime을 빼줌으로서 측정되는 적산시간(ms)를 1000ms=1sec로 나누고
		mili := mod((A_TickCount - InitTime), 1000) ; 정확한 시간 측정 위해 남는 값들(.000초)을 mili에 저장
		FormatTime RunTimeVal, %RunTime%, HH:mm:ss	
		GuiControl, , statRuntime, Runtime: %runtimeval%.%mili% 
		
		return

Run: 
F4:: ;Filereadline을 사용한 코드. 제대로 작동함. 
Gui, Submit, Nohide

rootpath = C:\ahktest\ ;csv파일을 저장할 폴더. 원래는 Gui를 통해 지정 가능함.


	InitTime := A_TickCount ; gRun시작되면서 (현재 컴퓨터 작동시간)InitTime 계산됨. 기준점
	SetTimer, Runtime_GUIUpdate, 10 ; 10ms마다 갱신되도록 함.
	
	
loop
{	
	FileReadLine, src, Input.txt, %A_Index%  ;Filereadline 제대로 작동함
	 if (ErrorLevel <> 0)
        break
	
	GuiControl, , Current, %a_index% ;현재 몇번째 줄 작업중인지 GUI에 표시

	if (instr(src, "##")>0) ;##으로 시작되는 문자열(##newsNHN 등등)
	{	
		subdir = % RegExreplace(src, "##","") ;IF문 검출 위한 구분자였던 ##을 제거 후 subdir에 저장
		FileCreateDir, %rootpath%\%subdir% ;아까 지정한 rootpath에 하위 디렉토리로서 subdir에 저장된 (newsNHN)을 폴더명으로 지정해 폴더 생성
		Filemove, %rootpath%\*, %rootpath%\%subdir% ;아래의 FILEAPPENED로 작성된 CSV파일들을 이동함.
		continue
	}
	
	;아래 Msgbox와 send는 원본에선 ImageSearch등을 비롯한 내용들인데, 질문 간략화 위해 이렇게 씁니다.	
	MsgBox ,,title, %src%, .5 
	;~ send, 손 반장은 수도권은 67.0명, 충청권은 13.6명, 경남권은 7.6명, 강원권은 6.1명 등이며 그 외 권역은 3명 이하 수준이라면서 최근 코로나19 환자가 조금씩 꾸준히 증가하고 있다고 설명했다. `n이어 현재와 같은 증가 추세가 계속된다면 거리두기 단계 조정기준도 2∼3주내에 충족할 가능성이 커진다며 천안, 아산, 원주, 순천 등 4개 시군구는 자체적으로 거리두기를 1.5단계로 격상한 바 있다고 설명했다. `n또 후보물질 유효성 평가시설 이용, 임상시험 신속 심사 등 요청 사항 223건을 처리했고 치료제·백신 임상시험에는 총 380억원을 지원하고 있다.
	
	
	FileAppend, MESSAGE, %rootpath%\%A_Index%.csv ;작업한 결과물 저장.
	sleep, 100

}

SetTimer, Runtime_GUIUpdate, off ;return 해서 종료 전에 타이머 꺼준다.(그렇지 않으면 다 끝나도 계속 돌아감)
return
	
f2::
Gui, Submit, Nohide


FileRead, src, Input.txt
rootpath = C:\ahktest\

	InitTime := A_TickCount
	SetTimer, Runtime_GUIUpdate, 10

Loop, Parse, src, `n ;Parse 사용시 폴더 하나만 생성됨(마지막 하나만)
{
	GuiControl, , Current, %a_index%
	RunTime = 20000101000000
	
	if (instr(A_LoopField, "##")>0)
	{
		subdir = % RegExreplace(A_LoopField, "##","")
		
		FileCreateDir, %rootpath%\%subdir%
		MsgBox %subdir%
		Filemove, %rootpath%\*, %rootpath%\%subdir%	
		continue
	}
	
	;원래는 ImageSearch등을 비롯한 내용들인데, 질문 간략화 위해 이렇게 씁니다.	
	MsgBox ,,title, %A_LoopField%, .5
	;~ send, 손 반장은 수도권은 67.0명, 충청권은 13.6명, 경남권은 7.6명, 강원권은 6.1명 등이며 그 외 권역은 3명 이하 수준이라면서 최근 코로나19 환자가 조금씩 꾸준히 증가하고 있다고 설명했다. `n이어 현재와 같은 증가 추세가 계속된다면 거리두기 단계 조정기준도 2∼3주내에 충족할 가능성이 커진다며 천안, 아산, 원주, 순천 등 4개 시군구는 자체적으로 거리두기를 1.5단계로 격상한 바 있다고 설명했다. `n또 후보물질 유효성 평가시설 이용, 임상시험 신속 심사 등 요청 사항 223건을 처리했고 치료제·백신 임상시험에는 총 380억원을 지원하고 있다.
	FileAppend, MESSAGE, %rootpath%\%A_Index%.csv
}
SetTimer, Runtime_GUIUpdate, off
return




GuiEscape:
GuiClose:
    ExitApp

흐름은 Input.txt에 있는 URL을 읽어들여 다운로드 등의 적절한 작업(길어서 SEND로 갈음했습니다.)을 하다가, '##WeatherNHN'과 같은 '##'으로 시작하는 문자열을 만나면 해당 문자열에서 RegExreplace로 ##을 떼낸 'WeatherNHN'을 mkdir해서 폴더를 만들고, 그 폴더에 작업한 결과물(*)을 폴더에 이동하는 것입니다.

 


1. 먼저 크리티컬한 부분은 아니지만 계속 신경쓰이는 부분은 A_TickCount에서의 문제점입니다. send나 imagesearch 사용하면 Runtime_GUIUpdate가 그 순간 멈춥니다. (send 써진 주석을 해제하고 실행해보시면 무슨 문제인지 이해되실 겁니다. :D)
2. 계속 FileReadLine을 쓰다가 강의에서 FileReadLine이 좋지 않다 하셔서 loop, parse로 바꾸게 되었는데요, F2에 작성한 코드가 그것입니다. 실행하면, 변수로는 잘 불러들이는 것 같은데, FileCreateDir이나 FileMove가 작동하지 않다가 마지막 부분만 작동합니다(sportesNHN)

물론 하던대로 FileReadLine쓰면 될 일이지만, 더 좋은 방법이 있는데 하지 않는 것도 조금 그래서 질문드립니다.

 

PS: 저만 회색으로 보이나요? 어떻게 하면 검정색으로 보일까요?

캡쳐.png

    • 글자 크기
댓글 7
  • 2020.11.12 21:32 댓글

    스크립트가 결과적으로 어떤 기능을 해야 하는지 설명해 주시면 좋을 것 같아요.

  • helper님께
    고구마호박글쓴이
    2020.11.12 23:07 댓글

    주석도 다시 달았습니다.

    잘 작동하는, 기존에 FileReadLine으로 작성했던 것을 기반으로 설명드리면

    rootpath에 C:\ahktest\ 를 지정. 작업공간으로 설정합니다.

    먼저, Input.txt의 내용을 FileReadLine으로 src라는 변수로 한줄씩 불러들여

    Line 1=Loop 1:(https://weather.naver.com/air/09140104)를 읽어들여 어떤 작업을 하고(너무 길어 여기엔 쓰지 않았지만), 그 결과물로서 rootpath에 csv파일을 Fileappend로 생성.

    Line 2=Loop 2:(https://weather.naver.com/today/09140104), 상동

    Line 3=Loop 3:(https://weather.naver.com/video/09140104), 상동

    Line 4=loop 4: ##WeatherNHN을 만나면, loop 초반에서의 if(instr(src. "##")>0)으로 조건이 true가 되어

    RegExreplace로 IF조건문 검출 위했던 ##이란 단어를 제거(WeatherNHN), 그것을 subdir이란 변수로 지정합니다.

    그 후, rootpath\subdir = (C:\ahktest\WeatherNHN)이란 폴더를 생성합니다.

    그 후, 그간 loop 1~3에서 저장된 csv파일을 모두 subdir(WeatherNHN)으로 이동합니다.

    다음 루프로

    Line 5=loop 5: (https://news.naver.com/main/main.nhn?mode=LSD&mid=shm&sid1=102), loop 1~3에서의 작업과 같음

    line 6=loop 6: (https://news.naver.com/main/main.nhn?mode=LSD&mid=shm&sid1=101), 상동

    line 7=loop 7: (##newsNHN), LOOP 4에서의 작업과 같음. LOOP 5~6에서 작업했던 CSV를 newsNHN이란 폴더를 만들어 그 폴더에 이동시킴.

    Line 8=loop 8: (https://sports.news.naver.com/kbaseball/index.nhn), loop 1~3에서의 작업과 같음

    line 9=loop 9: (https://sports.news.naver.com/kfootball/index.nhn), 상동

    line 10=loop 10: (https://sports.news.naver.com/wbaseball/index.nhn), 상동

    line 11=loop 11: (##sportsNHN), LOOP 4에서의 작업과 같음. LOOP 8~10에서 작업했던 CSV를 sportsNHN이란 폴더를 만들어 그 폴더에 이동시킴.

     

    문제는, 이것을 FileReadLine이 아닌 Loop, Parse로 바꾸면서인데,

    FileCreateDir을 하면 마지막 LINE 11: sportsNHN만 디렉토리가 생성됩니다. 아예 작동하지 않으면 이해하겠는데, 마지막만 작동되니 이상합니다.

     

    Runtime_GUIUpdate에서의 문제는, IMAGESEARCH나 SEND 등의 작업을 하면 그동안 Runtime_GUIUpdate가 중단되는 것(처럼 보이는)입니다. 물론 해당 명령을 지나면 정상적으로 표시되지만, 뭔가 찝찝해서 문의 남겼습니다.

  • 2020.11.12 22:46 댓글

    아래와 같은 경로를 사용하는데요, rootpath에는 \ 기호가 이미 있어서 전체 경로는 C:\ahktest\\~~~~ 이렇게 될 것 같습니다. rootpath변수에 마지막 \를 떼보세요.

    %rootpath%\%subdir%

     

    오토핫키는 인터프리터 언어이고, 단일 스레드만 이용하기 때문에 한 명령어에서 정체된다면 다른 명령어는 진행되지 않습니다. 기본적으론요.

    Runtime_GUIUpdate가 멈추는 이유 또한 같습니다. send로 오래 입력하고 있기 때문입니다.

     

     

  • 프날님께
    고구마호박글쓴이
    2020.11.12 23:19 댓글

    올려드린 코드도 그렇지만, Loop, Parse를 이용한 모든 명령에서 정상적으로 FileCreateDir, %rootpath%\%subdir%이 실행되는건 마지막 line11, ##sportsNHN만 됩니다.

     

    프날님이 말씀하신 것처럼

    FileCreateDir, C:\ahktest\%subdir% 도 해봤는데 작동되지 않아서, 아예

    FileCreateDir, %subdir% 도 해봤는데 작동되지 않네요. (SetWorkingDir %A_ScriptDir% 이니까 ahk파일이 있는 폴더에 저장되겠죠)

    Fileappend, test, %subdir%.txt 도 마찬가지고요.

     

    혹시나 해서

    sportsNHN.txt, sportsNHN.txt, WeatherNHN.txt도 만들어

    Filemove, C:\ahktest\%SUBDIR%.TXT, C:\

    도 해봤는데, 역시나 마지막 11번 sportsNHN.txt만 옮겨지네요. 아예 %subdir%을 인식하지 못하는것처럼요.

    근데 그렇다면 마지막 11번은 작동하지 않아야 하는데, 이것만은 작동하니 ㅠㅠ...

  • 고구마호박글쓴이
    2020.11.13 08:49 댓글

    아예 if니 RegEX니 GUI니 하는거  다 때내고

    Input.txt 내용
    Test1
    Test2
    Test3
    Test4
    
    ;;;;;;;코드 시작;;;;;;;
    #SingleInstance Force
    #NoEnv
    SetWorkingDir %A_ScriptDir%
    SetBatchLines -1
    
    F2::
    
    
    FileRead, src, input.txt
    Loop, Parse, src, `n
    {
    
    	msgbox, ,,%a_loopfield%, .5
    	FileAppend, message, %a_loopfield%.txt
    	FileAppend, MESSAGE, %A_Index%.csv
    
    }
    
    Return

    으로 해봤는데도 마지막 줄만 생성 (Test4.txt) 됩니다. %a_index%로 생성되는건 (.csv) 모두 작동하고요.

  • 고구마호박님께
    2020.11.13 21:00 댓글

    Loop, Parse로 끊어온 문자열을 바로 FileAppend로 쓰셔서 그렇습니다.
    왜냐하면 파일을 저장하면 한칸 개행은 `n이 아니라 `r`n으로 들어가기 때문입니다. `r은 커서를 맨 앞으로 옮기라는 캐리지리턴, `n은 한 줄 밑으로 내려가는 엔터의 역할입니다.
    텍스트파일의 내용이 아래와 같다고 해봅시다.

    Test1
    Test2

    그러면 실제로 아래와 같은 내용을 가지고 있습니다. (`r`n은 실제로 표시되지 않고 '줄바꿈'의 형태로 드러나는 점을 알아두세요. )

    Test1`r`nTest2

     

    이거를 Loop, Parse로 `n을 기준으로 끊어봅시다. (다시, `r은 실제로 보이지 않는 문자입니다.)

    [1] Test1`r
    [2] Test2

    첫번째 불러온 내용을 파일명으로 쓸 수 있을까요? 아닙니다. 파일명에 특수한 문자가 들어갔으니까요. ('엔터'를 파일명에 못쓰듯이요.)

     

    따라서, 아래와 같이 `r을 omitchar로 지정해서 테스트해보시면

    정상적으로 사용가능합니다. (Loop, Parse, src, `n, `r에서 `r은 '`r을 생략하겠다'라는 뜻입니다.)

    FileRead, src, input.txt
    Loop, Parse, src, `n, `r
    {
    	FileAppend, message, %a_loopfield%.txt
    	FileAppend, MESSAGE, %A_Index%.csv
    }

     

  • 프날님께
    고구마호박글쓴이
    2020.11.14 23:54 댓글

    그랬군요... txt에서도 CR이 들어갔네요. csv파일 개행할 때 `r`n으로 쓰던 기억은 있었는데 말이죠.. 방금 fileappend로 txt 쓸 때는 어떤가 봤는데 CR이 자동으로 붙네요. 쓸 때는 자동으로 붙는데 읽을 때는 자동으로 안붙다니.... 마지막 루프에는 CR이 없으니 당연히 실행되는 거였네요.

    답변 감사합니다. 좋은 밤 되세요.

댓글 달기

서버에 요청 중입니다. 잠시만 기다려 주십시오...