[windows] batch script

spring·2020년 11월 9일
0
  • 배치파일은 무조건 ANSI로 저장한다.


1. 디렉토리 목록 조회

@echo off
SETLOCAL EnableDelayedExpansion
FOR /R %%E IN (3rdparty/include/*.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')"

가능하다면 curl 을 쓰는것이 좋다. 대용량의 파일의 경우에는 위의 방법이 실패할 수 도 있다.

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

23. 출력 결과 숨기기

COMMAND >nul 2>&1

뒤에 >nul 2>&1 을 붙여 주면 된다.

24. 프로그램의 존재 유무 확인

:ProgramExistInit
set PEI=0
exit /b
:ProgramExistTest
where %~1 >nul 2>&1
set /a PEI=%PEI%+%ERRORLEVEL%
exit /b

위와 같은 함수를 정의 하고 아래와 같이 테스트 한다.

call :ProgramExistInit
call :ProgramExistTest python
call :ProgramExistTest cmake
call :ProgramExistTest git
if %PEI% EQU 0 (
   echo Program exist
)

25. 디렉토리 이동시 드라이브도 이동

cd 명령어는 기본적으로 드라이브가 다르면 이동하지 않는다. /D 옵션으로 드라이브를 이동할 수 있다.

cd /D %TEMP%

26. 현재 실행된 배치파일 이름 알아오기

echo %~dp0               <전체 경로>
echo %~n0                <확장자를 제외한 파일 이름>
echo %~x0                <확장자>
echo %~nx0               <확장자를 포함한 파일 이름>

27. 프로그램 출력 결과 변수로 가져오기

아래 예시는 nvcc의 위치를 출력하고 변수로 가져오는 방법이다.
set /p 구문에서 문자열로 감싼 범위를 주의해야 한다.

where nvcc > "%temp%\cudapath.txt"
set /p "cudapath="<"%TEMP%\cudapath.txt"

28. 프로그램의 출력(stdout)이 있는지 없는지 확인하는 방법

adb devices | grep %android_device% > %TEMP%\%~n0.tmp
for %%A in ("%TEMP%\%~n0.tmp") do (
    if %%~zA EQU 0 (
        echo Device is not attatched!
		pause
		exit /b
    )
)

29. 출력 색상 지정

powershell의 write-host를 쓰는게 제일 편하다.

@echo off

powershell write-host -fore Cyan hello, world
powershell write-host -back Red where is comma
powershell write-host -fore Green -back Red Green on Red

30. 현재시간으로 변수 만들기

아래처름 %time%은 hour가 1자리일 때 공백이 생기는 문제와 :는 파일명으로 사용할 수 없는 문자여서 slicing과 replace를 사용하여 처리한다.

#echo %date%
2023-06-24
#echo %time%
 0:53:11.74
set CTIME=%time: =0%
echo %DATE:~0,4%%DATE:~5,2%%DATE:~8,2%_%CTIME:~0,2%%CTIME:~3,2%%CTIME:~6,2%.mp4
# 20230624_005443.mp4

31. 임시파일 만들기

임시폴더에 시간 변수를 포함하여 가능한 겹치지 않는 임시파일을 만드는 방법.

출력 예시: C:\Users\spring\AppData\Local\Temp\20240518-125039.txt

set "extension=.txt"
set "datetime=%date:~0,4%%date:~5,2%%date:~8,2%-%time:~0,2%%time:~3,2%%time:~6,2%"
set "datetime=%datetime: =0%"
set "datetime=%datetime::=-%"
set "datetime=%datetime:.=%"
set "temp_file=%TEMP%\%datetime%%extension%"
echo %temp_file%
profile
Researcher & Developer @ NAVER Corp | Designer @ HONGIK Univ.

0개의 댓글