2013-10-30 30 views
1

目前我有一个循环遍历项目列表并将它们复制到目录(存档)。但是,列表中的其中一项(在路径名中包含全局变量)正在被'逐字'解释(作为文本而不是代码)。 我知道通常你可以通过(^^)将它解释为代码而不是文本,但显然我在这里做错了什么,因为它不工作...批处理文件:防止for/f循环中的字面解释

The item in the my.list(在它逃跑),它有问题是:

location\foo^^%date:~0,3%*.zip 

我正在使用的代码是...

for /f "delims=" %%a in (my.list) do (
    echo "%%a" 
) 

Echo的

"location\foo^^%date:~0,3%*.zip" 

而不是

location\fooMON*.zip 

任何帮助将不胜感激。

+0

'call echo“%% a”'? – npocmaka

回答

4

对于什么时候需要转义角色,你感到困惑。

有些字符有特殊含义(如您所描述的“代码”)。通常情况下,您可以转义字符,以便将其解释为文字(文本)而不是“代码”。

在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循环逐字读取文本行,无需任何扩展。解析器第一次看到您的“代码”是在步骤3)时扩展%%a FOR变量。您可以看到,现在已经太迟,无法按照您的要求扩展 %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" 

但现在你有你可能有一个!文字在列表中,你做希望扩大潜在的问题。您可以通过将它们转义为^!来保留!文字。