use*_*294 1 windows for-loop cmd escaping batch-file
目前,我有一个循环遍历项目列表并将它们复制到目录(存档)。但是,列表中的一项(路径名中有一个全局变量)被“字面”解释(作为文本而不是代码)。我知道通常你可以通过 (^^) 转义该行,将其解释为代码而不是文本,但显然我在这里做错了什么,因为它不起作用......
my.list 中存在问题的项目(其中包含转义符)是:
location\foo^^%date:~0,3%*.zip
Run Code Online (Sandbox Code Playgroud)
我正在使用的代码是...
for /f "delims=" %%a in (my.list) do (
echo "%%a"
)
Run Code Online (Sandbox Code Playgroud)
回声的
"location\foo^^%date:~0,3%*.zip"
Run Code Online (Sandbox Code Playgroud)
代替
location\fooMON*.zip
Run Code Online (Sandbox Code Playgroud)
任何帮助将不胜感激。
您对于何时需要转义角色感到困惑。
有些字符具有特殊含义(如您所描述的“代码”)。通常,您可以转义字符,以便将其解释为文字(文本)而不是“代码”。
在 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) 中,当%%aFOR 变量展开时。您可以看到,现在已经太晚了,无法按照
%date:~0,3%您想要的方式进行扩展。
您有两种选择来解决您的问题。但请注意 - 这些解决方案中的每一个都可能会增加可能需要解决的新问题。
我假设这^^是您天真的尝试强制扩展嵌入的“代码”。应该^^从您的列表文件中删除。
方案1:使用CALL额外增加一轮正常扩展
for /f "delims=" %%a in (my.list) do call echo "%%a"
Run Code Online (Sandbox Code Playgroud)
但现在您有一个潜在的问题,您的列表中可能有一个您不想扩展的%文字。批处理脚本中的百分比不能用 转义。相反,您可以通过将其加倍为 来逃避百分比。因此,如果列表中有百分比文字,则它们必须加倍。^%%
请注意,随问题发布的原始代码要复杂得多。它包括一个引用 的 IF 语句%%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.
)
Run Code Online (Sandbox Code Playgroud)
选项 2:使用延迟扩展
启用延迟扩展,并将列表更改为!date:~0,3!使用%date:~0,3%. 延迟扩展发生在FOR变量扩展之后,因此会正确扩展。
setlocal enableDelayedExpansion
for /f "delims=" %%a in (my.list) do echo "%%a"
Run Code Online (Sandbox Code Playgroud)
但现在您有一个潜在的问题,您的列表中可能有一个您不想扩展的!文字。您可以通过将文字转义为 来保留文字。!^!