[windows] batch script

1. 디렉토리 목록 조회

@echo off
SETLOCAL EnableDelayedExpansion
FOR /R %%E IN (SogangComputerVisionLibrary/SCVL/*.h) DO (
	set full_path=%%E
	set file=%%~nxE
	echo !full_path!
	echo !file!
)

기본적으로 %%E 에는 full_path가 들어가 있다.

%%~nE는 순수한 파일명만 뽑아내고

%%~nxE는 확장자를 포함한 파일명만 추출한다.

또한 for문 내부에서 변수를 사용하려면 앞의 SETLOCAL ENABLEDELAYEDEXPANSION를 사용해야 한다.

2.주석

한줄 주석은 ::으로 시작한다. 다중 주석은 goto 문으로 해결한다.

::This is comment

goto COMMENT
::looks like multiline comment
:COMMENT

3. 파일 읽기

3.1 전체 파일 읽기

@echo off
setlocal EnableDelayedExpansion
set LF=^


::반드시 두줄 띄워야 함
set "content="

for /f "delims=" %%x in (file.txt) do (
  set "content=!content!%%x!LF!"
)
echo !content!
endlocal

3.2 한줄 읽기

set /p "content="<"file.txt"

4.수식 연산

set idx=0
set /A idx=idx+1

5.배열

@echo off
setlocal EnableDelayedExpansion
set list=
FOR /L %%i in (0,1,10) do (
	set list[%%i]=%%i
)
echo ----
FOR /L %%i in (0,1,10) do (
	echo !list[%%i]!
)
endlocal

6.String replace

setlocal ENABLEDELAYEDEXPANSION
set word=table
set str="jump over the chair"
set str=%str:chair=!word!%

7.지연확장에서의 배열 인덱스(이걸 해야 한다면 perl이나 python을 써라)

배열을 **!**로 감싸야 하는 환경에서 인덱스 까지 **!**로 감쌀순 없다.
이때 함수호출을 이용해 대신 쓸수 있다.

@echo off
setlocal EnableDelayedExpansion
FOR /L %%i in (0,1,10) do (
	set list[%%i]=##%%i##
)
set idx=0

echo ----

FOR /L %%i in (0,1,10) do (
	echo Element : !list[%%i]!
	set /A idx=!idx!+1
	call :FOO !idx!
)

endlocal

:FOO
echo !list[%1]!

8.웹에서 파일 다운로드

powershell "(New-Object System.Net.WebClient).DownloadFile('http://url.sample','filename.sample')"

9. 압축 풀기

powershell.exe -nologo -noprofile -command "& { Add-Type -A 'System.IO.Compression.FileSystem'; [IO.Compression.ZipFile]::ExtractToDirectory('foo.zip', 'bar'); }"

10. 폴더 삭제

IF EXIST "folder" (  
    RMDIR /S /Q "folder"
)

11. 파일 삭제

IF EXIST "file" (
	DEL "file"
)

12. 다른 배치파일 실행

call other.bat

call 을 쓰지 않으면 배치파일이 실행한 배치파일로 대치되어 밑에 구문들이 실행되지 않는다.

13. 함수

call :SafeDEL "*.pdb"
call :SafeRMDIR "x64"
exit /b
:SafeDEL
IF EXIST "%~1" (
	DEL "%~1"
)
exit /b

:SafeRMDIR
IF EXIST "%~1" (
	RMDIR /S /Q "%~1"
)
exit /b

위와 같은 간단한 방법으로 함수를 만들수 있다.

14. 파일 복사

xcopy /Y "a\*.exe" "b\"

중요한 점은 경로에 slash 를 쓰면 안되고 back-slash 를 써야 한다.
slash는 옵션에서 사용되기 때문인것 같다.
/Y 는 덮어쓰기 허용 옵션이다.

xcopy /d /i /Y "a\*.exe" "b\"

/d /i 옵션은 이미 존재하는 파일인 경우 건너뛴다는 옵션이다.

15. 관리자 권한 획득

아래 코드를 첫부분에 넣어주면 UAC를 띄우고 관리자 권한을 얻는다.

@echo off
>nul 2>&1 "%SYSTEMROOT%\system32\cacls.exe" "%SYSTEMROOT%\system32\config\system"
if '%errorlevel%' NEQ '0' (
    echo Get admin permission...
    goto UACPrompt
) else ( goto gotAdmin )
:UACPrompt
    echo Set UAC = CreateObject^("Shell.Application"^) > "%temp%\getadmin.vbs"
    set params = %*:"=""
    echo UAC.ShellExecute "cmd.exe", "/c %~s0 %params%", "", "runas", 1 >> "%temp%\getadmin.vbs"
    "%temp%\getadmin.vbs"
    rem del "%temp%\getadmin.vbs"
    exit /B
:gotAdmin
pushd "%CD%"
CD /D "%~dp0"

16. thread 개수

%NUMBER_OF_PROCESSORS%

17. 대기

timeout /t 5 /nobreak > NUL

5초를 대기하는 코드 이다.

18. HTML 코드파싱하기

powershell "$HTML=Invoke-WebRequest -Uri 'https://www.google.co.kr/';($HTML.ParsedHtml.getElementsByTagName('a') | %% href) > parse.txt"

위는 모든 a태그의 href를 출력하는 명령어이다.

19. 문자열 파싱하기

powershell "get-content parse.txt -ReadCount 1000 | foreach { $_ -match 'abcd' } | out-file -encoding ascii link.txt"

텍스트파일에서 abcd가 있는 줄만 따로 출력하는 명령어 이다.

20. Invoke-WebRequest Fails with SSL/TLS Secure Channel

이 문제가 발생할땐 아래의 구문을 실행한뒤, 웹 모듈을 실행하여야 한다.

[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

21. 파일 크기 알아오기

:GetFileSize
set FILESIZE=%~z1
exit /b
call :GetFileSize "README.md"
echo %FILESIZE%

함수로 작성하여만 한다. 함수 내부에서 %~z1 을 환경변수에 넣고, 함수 호출한뒤 그 값을 사용하는 방식이다.
https://code.i-harness.com/ko/q/124e1d

22. 폰트 설치

call :FONT "BMYEONSUNG_ttf.ttf"
exit /b

:FONT
SET FFILE=%~n1%~x1
SET FNAME=%~n1
SET FNAME=%FNAME:-= %
IF "%~x1"==".otf" SET FTYPE=(OpenType)
IF "%~x1"==".ttf" SET FTYPE=(TrueType)
COPY /Y "%~n1%~x1" "%SystemRoot%\Fonts\" >nul
reg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts" /v "%FNAME% %FTYPE%" /t REG_SZ /d "%FFILE%" /f >nul
exit /b