배치 파일에서 하위 문자열을 수행하는 가장 좋은 방법은 무엇입니까?


192

파일 확장자 없이 현재 실행중인 배치 파일의 이름을 얻고 싶습니다 .

덕분에 이 링크는 , 나는 파일 이름이 가진 확장을 ...하지만 배치 파일에서 문자열을 할 수있는 가장 좋은 방법은 무엇입니까?

아니면 확장자가없는 파일 이름을 얻는 다른 방법이 있습니까?

이 시나리오에서는 3 글자 확장명을 사용하는 것이 안전합니다.

답변:


398

배치의 파일 이름을 얻는 가장 쉬운 방법은을 사용하는 것 %~n0입니다.

@echo %~n0

는 현재 실행중인 배치 파일의 이름 (확장자없이)을 출력합니다 (에 의해 호출 된 서브 루틴에서 실행되지 않은 경우 call). 경로 이름에 대한 이러한 "특별한"대체 목록은 help for도움말 맨 끝에서 찾을 수 있습니다 .

또한 FOR 변수 참조의 대체가 향상되었습니다. 이제 다음과 같은 선택적 구문을 사용할 수 있습니다.

%~I         - expands %I removing any surrounding quotes (")
%~fI        - expands %I to a fully qualified path name
%~dI        - expands %I to a drive letter only
%~pI        - expands %I to a path only
%~nI        - expands %I to a file name only
%~xI        - expands %I to a file extension only
%~sI        - expanded path contains short names only
%~aI        - expands %I to file attributes of file
%~tI        - expands %I to date/time of file
%~zI        - expands %I to size of file
%~$PATH:I   - searches the directories listed in the PATH
               environment variable and expands %I to the
               fully qualified name of the first one found.
               If the environment variable name is not
               defined or the file is not found by the
               search, then this modifier expands to the
               empty string

수정자를 결합하여 복합 결과를 얻을 수 있습니다.

%~dpI       - expands %I to a drive letter and path only
%~nxI       - expands %I to a file name and extension only
%~fsI       - expands %I to a full path name with short names only

그러나 귀하의 질문에 정확하게 대답하기 위해 : 부분 문자열은 다음 :~start,length표기법을 사용하여 수행 됩니다.

%var:~10,5%

환경 변수의 위치 10에서 5자를 추출합니다 %var%.

참고 : 문자열의 인덱스는 0부터 시작하므로 첫 번째 문자는 위치 0에 있고 두 번째 문자는 1에 있습니다.

같은 인수 변수의 문자열을 얻으려면 %0, %1등 당신은 정상적인 환경 변수 사용에 할당해야 할 set첫째 :

:: Does not work:
@echo %1:~10,5

:: Assign argument to local variable first:
set var=%1
@echo %var:~10,5%

구문은 훨씬 강력합니다.

  • %var:~-7% 에서 마지막 7자를 추출합니다 %var%
  • %var:~0,-4%마지막 네 개를 제외한 모든 문자를 추출하여 파일 확장자를 제거합니다 (마침표 [ .] 뒤에 세 문자를 가정 ).

help set해당 구문에 대한 자세한 내용을 참조하십시오 .


31
부분 문자열 추출은 FOR 루프 변수와 함께 작동하지 않으므로 다음과 같이해야합니다 (코멘트에서 \ r \ n은 주석에서 줄 바꿈을 허용하지 않기 때문에 줄 바꿈을 의미합니다) :setlocal ENABLEDELAYEDEXPANSION \r\n for /f %%s in ('set') do ( \r\n set tmp=%%s \r\n echo !tmp:~-3! \r\n )
Fr0sT

@ Fr0sT 왜 FOR루프 를 위해 이것을해야 합니까?
Bob

4
@ 아드리안 왜 안돼? FOR꽤 많은 수의 다양한 작업을 수행하는 배치 파일의 초석입니다. Btw, 서브 루틴을 사용하여 작업을 처리하는 또 다른 방법이 있습니다. 즉for /f %%s in ('set') do call :DoSmth "%%s" \r\n ... \r\n :DoSmth \r\n set var=%1 \r\n echo %var:~1,3%
Fr0sT

1
Windows Server 12 R2를 사용하면 % date %는 21/05/18 (IT culture)처럼 보입니다. 오른쪽 문자열은 다음과 같습니다. %date:~0,2%%date:~3,2%%date:~6,4%%time:~0,2%%time:~3,2%%time:~6,2%
Phate01

@ Phate01, %date%특정 형식으로 날짜를 구성하는 데 사용하지 마십시오 . 형식은 사용자 문화에 따라 다르며 변경 될 수 있습니다. 대신 사용자 설정에 의존하지 않는 유용한 형식으로 날짜와 시간을 얻으려면 WMI를 사용하십시오. 또한이 질문이 날짜 또는 시간에 관한 것이 아니기 때문에이 의견이 무엇을하고 있는지 잘 모르겠습니다.
Joey

38

위의 멋진 설명!

현지화 된 Windows 에서이 작업을 수행하는 데 어려움을 겪을 수있는 모든 사람들 (광산은 슬로바키아어에서 XP입니다) %에 대해!

그래서:

SET TEXT=Hello World
SET SUBSTRING=!TEXT:~3,5!
ECHO !SUBSTRING!

27
이것은 setlocal ENABLEDELAYEDEXPANSION명령 후에 만 작동합니다
Fr0sT

13

Joey의 답변에 대한 추가 정보로 set /?nor 의 도움으로 설명되지 않았습니다 for /?.

%~0입력 한대로 정확하게 자신의 배치 이름으로 확장됩니다.
따라서 배치를 시작하면 다음과 같이 확장됩니다.

%~0   - mYbAtCh
%~n0  - mybatch
%~nx0 - mybatch.bat

그러나 한 가지 예외가 있습니다. 서브 루틴 확장은 실패 할 수 있습니다

echo main- %~0
call :myFunction
exit /b

:myFunction
echo func - %~0
echo func - %~n0
exit /b

결과는

main - myBatch
Func - :myFunction
func - mybatch

함수 %~0에서 배치 파일이 아닌 함수 이름으로 항상 확장됩니다.
그러나 하나 이상의 수정자를 사용하면 파일 이름이 다시 표시됩니다!

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.