문자를 이스케이프해야 할 때를 혼동합니다.
일부 문자는 특별한 의미가 있습니다 (설명 할 때 "코드"). 문자를 "코드"대신 리터럴 (텍스트)으로 해석하도록 문자를 이스케이프 할 수있는 경우가 종종 있습니다.
Windows CMD.EXE에서 문자를 이스케이프하는 가장 일반적인 방법은 단일 ^
문자 앞에 접두사를 붙이는 것입니다. 때로는 문자열이 두 번 구문 분석되며, 이는 지연 확장이 활성화 된 경우 !
을 처리 할 때 ^^^
(또는 아마도 ^^
)의 이스케이프 시퀀스가 필요할 수 있습니다. 파싱을 더 많이 수행하려면 ^
자를 더 필요로합니다. 그것은 빨리 혼란스러워 질 수 있고, 그것에 매달린 연습이 필요합니다.
그러나 상황은 완전히 다릅니다. 즉 탈출하여 해결할 수 없습니다. FOR 변수 내에 "코드"가 있으며 그 코드로 해석되기를 원합니다. 그러나 대신 텍스트로 해석됩니다. 이유를 이해하려면 일괄 처리 구문 분석의 여러 단계가 발생하는 순서를 이해해야합니다. 당신은 How does the Windows Command Interpreter (CMD.EXE) parse scripts?을 참조 할 수 있습니다. 그러나 그것은 소화하는데 시간이 걸리는 꽤 발전된 것들입니다.
다음은 다양한 유형의 확장이 발생할 때 나타나는 조잡한 개요입니다. (참고 -이 단계 번호는 링크 된 대답의 위상 번호와 정확히 일치하지 않음) - %1
2) 일반 변수 확장 - %var%
3) 변수 확장을위한 - %%A
1) 매개 변수 확장 4) 지연 변수 확장 - !var!
5) CALL 확장 - 단계를 반복 1)과 2) CALL이
를 포함하면 당신은 당신의
%date:~0,3%
문자열이 정상 (퍼센트) 확장을 받아야합니다. FOR 루프는 확장하지 않고 텍스트 줄을 축 어적으로 읽습니다. 파서가 처음으로 "코드"를 보게되면
%%a
FOR 변수가 확장 될 때 3 단계에서 발생합니다. 이미 너무 늦어서
%date:~0,3%
을 원하는 방식으로 확장 할 수 없음을 알 수 있습니다.
두 가지 방법으로 문제를 해결할 수 있습니다. 하지만주의해야 할 점은 이러한 솔루션 각각은 잠재적으로 해결해야 할 새로운 문제를 추가 할 수 있다는 점입니다.
^^
은 임베디드 "코드"를 강제 확장하려는 순진한 시도라고 가정합니다. ^^
은 목록 파일에서 제거해야합니다.
옵션 1 : CALL
for /f "delims=" %%a in (my.list) do call echo "%%a"
를 사용하여 일반 확장의 추가 라운드를 추가하지만 지금 당신은 잠재적 인 문제가 당신이 을하지 않는 당신의 목록에서 %
문자가있을 수 있습니다 확장하고 싶습니다. 배치 스크립트 내의 퍼센트는 ^
으로 이스케이프 할 수 없습니다. 대신 당신은 %%
로 그것을 두배로하여 퍼센트를 벗어납니다. 따라서 목록에 백분율 리터럴이 있으면 두 배로 늘려야합니다.
질문과 함께 게시 된 원래 코드는 훨씬 더 복잡했습니다. %%a
을 참조한 IF 문이 포함되었습니다. IF 또는 FOR 명령을 호출 할 수 없습니다. 해결 방법은 서브 루틴을 호출하여 값을 전달하고 복잡한 논리를 서브 루틴에 포함시키는 것입니다.
for /f "delims=" %%a in (my.list) do call :processValue "%%a" >>Logs\xfer.log
exit /b
:processValue
echo Attempting to archive %1...
if exist "c:\%~1" (
echo f | xcopy "c:\%%a" "c:\Lucas\archive\%~1" /E /C /H /R /Y
if %errorlevel%==0 (
echo ...%1 added to archive for transfer
echo.
) else (
echo ERROR: %1 not added to archive
echo.
)
) else (
echo ERROR: %1 Not found on client computer
echo.
)
옵션 2 : 사용
가 !date:~0,3!
대신 %date:~0,3%
사용하도록 목록을 지연 확장을 활성화하고 변경 확장 지연. 지연된 확장은 FOR 변수 확장 이후에 발생하므로 올바르게 확장됩니다.
setlocal enableDelayedExpansion
for /f "delims=" %%a in (my.list) do echo "%%a"
그러나 지금 당신은 당신이 확장되고 싶지 할 목록에 !
문자가있을 수 있습니다 잠재적 인 문제가있다. !
리터럴을 ^!
으로 이스케이프 처리하여 보존 할 수 있습니다.
약'call echo "%% a"'? – npocmaka