您对何时需要转义字符感到困惑。
某些字符具有特殊含义(如您所描述的“代码”)。通常,您可以转义字符,以便将其解释为文字(文本)而不是“代码”。
在 Windows CMD.EXE 中转义字符的最常用方法是在其前面加上一个^
字符。有时一个字符串会被解析两次,这可能需要一个转义序列^^^
, (或者可能在启用延迟扩展^^
时进行处理)。!
更多轮次的解析需要更多的^
字符。它很快就会变得混乱,需要练习才能掌握它。
但你的情况完全不同——它不能通过逃避来解决。您的 FOR 变量中有“代码”,并且您希望它被解释为这样。但相反,它被解释为文本。为了理解原因,您必须了解批处理解析的各个阶段发生的顺序。您可以参考Windows 命令解释器 (CMD.EXE) 如何解析脚本?,但它是相当高级的东西,需要时间来消化。
这是一个粗略的概要,显示何时发生各种类型的扩展。(注意 - 这些步骤编号与链接答案的阶段编号不完全匹配)
1) 参数扩展 - %1
2) 普通变量扩展 - %var%
3) FOR 变量扩展 - %%A
4) 延迟变量扩展 - !var!
5) CALL 扩展 - 如果涉及 CALL,则重复步骤 1) 和 2)
您希望您的%date:~0,3%
字符串进行正常(百分比)扩展。您的 FOR 循环逐字读取文本行,没有任何扩展。解析器第一次看到您的“代码”是在步骤 3)%%a
扩展 FOR 变量时。您可以看到,要
%date:~0,3%
以您想要的方式扩展已经为时已晚。
你有两个选择来解决你的问题。但请注意 - 这些解决方案中的每一个都可能会增加可能需要解决的新问题。
我假设这^^
是您天真地尝试强制扩展嵌入式“代码”。应该从您的列表文件中删除。^^
选项 1:使用 CALL 添加额外一轮正常扩展
for /f "delims=" %%a in (my.list) do call echo "%%a"
但是现在你有一个潜在的问题,你%
的列表中可能有一个你不想被扩展的文字。批处理脚本中的百分比不能用^
. 相反,您通过将其加倍来逃避一个百分比%%
。因此,如果您的列表中有百分比文字,则它们必须加倍。
请注意,随问题发布的原始代码要复杂得多。它包括一个引用%%a
. 您不能 CALL 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"
但是现在你有一个潜在的问题,你!
的列表中可能有一个你不想被扩展的文字。您可以!
通过将文字转义为^!
.