当扩展变量包含"%"时,使用调用来传递由变量表示的值时遇到问题。在字符串中。我知道,就个人而言,我只会使用转义字符(大概是%%),但这些变量来自其他人创建的文件夹名称,并根据他们的想法改变。
我尝试了多种不同的修复和一些诊断尝试(如下所示)。
代码示例:(setlocal EnableDelayedExpansion)
:findMostRecentFiles
REM call :findMostRecentFiles %productFile% %pathPrefix% %resultFile%
break>%~3
For /f "tokens=* delims=" %%g In (%~1) Do (
set fullFolderPath=%~2\%%g\
Echo !fullFolderPath!
Echo !fullFolderPath!>>%~3
Echo Calling findMostRecentFile:
call :findMostRecentFile "!fullFolderPath!" "%~3"
)
goto :eof
:findMostRecentFile
:: REM call :findMostRecentFile "!fullFolderPath!" %~3
:: Echo %~1
Echo Checking FullFolderPath (no quotes): %~1
Echo Checking FullFolderPath (quotes): "%~1"
Echo Checking resultFile: %~2
Echo About to push: "%~1"
Pushd "%~1"
cd
popd
goto :eof
结果部分:
set fullFolderPath=S:\QA\BA 25% TMAH\
Echo !fullFolderPath!
Echo !fullFolderPath! 1>>C:\Users\M2\Desktop\ProductList_Recent.txt
Echo Calling findMostRecentFile:
call :findMostRecentFile "!fullFolderPath!" "C:\Users\M2\Desktop\ProductList_Recent.txt"
)
S:\QA\BA 25% TMAH\
Calling findMostRecentFile:
S:\QA>Echo Checking FullFolderPath (no quotes): S:\QA\BA 25\Users\M2\Desktop\Produc
tList_Recent.txt
Checking FullFolderPath (no quotes): S:\QA\BA 25\Users\M2\Desktop\ProductList_Recent.txt
S:\QA>Echo Checking FullFolderPath (quotes): "S:\QA\BA 25\Users\M2\Desktop\ProductL
ist_Recent.txt"
Checking FullFolderPath (quotes): "S:\QA\BA 25\Users\M2\Desktop\ProductList_Recent.
txt"
S:\QA>Echo Checking resultFile:
Checking resultFile:
S:\QA>Echo About to push: "S:\QA\BA 25\Users\M2\Desktop\ProductList_Recent.tx
t"
About to push: "S:\QA\BA 25\Users\M2\Desktop\ProductList_Recent.txt"
S:\QA>Pushd "S:\QA\BA 25\Users\M2\Desktop\ProductList_Recent.txt"
The system cannot find the path specified.
它正在以一种我没有预料到的方式处理扩展变量(虽然显然是我所写的正确行为)并且我不知道如何制作它以便当 fullFolderPath 包含"%"它作为自己的值传递,而不是与传递给调用的其他变量连接。
任何帮助或解释都会很棒!
答案 0 :(得分:0)
可能的解决方法是将变量名称传递给子例程而不是值,并在那里应用延迟扩展。
以下是修改后的代码:
setlocal EnableDelayedExpansion
:findMostRecentFiles
REM call :findMostRecentFiles %productFile% %pathPrefix% %resultFile%
break>%~3
For /f "tokens=* delims=" %%g In (%~1) Do (
set fullFolderPath=%~2\%%g\
Echo !fullFolderPath!
Echo !fullFolderPath!>>%~3
Echo Calling findMostRecentFile:
call :findMostRecentFile fullFolderPath "%~3"
)
goto :eof
:findMostRecentFile
:: REM call :findMostRecentFile fullFolderPath %~3
:: Echo !%~1!
Echo Checking FullFolderPath (no quotes): !%~1!
Echo Checking FullFolderPath (quotes): "!%~1!"
Echo Checking resultFile: %~2
Echo About to push: "!%~1!"
Pushd "!%~1!"
cd
popd
goto :eof
代码中的问题是子程序参数扩展在命令解释器中很早就发生了,甚至在立即(%
)变量扩展之前。如果参数中出现一个%
个字符,它就会消失。如果有两个%
个字符,则其间的所有内容都被视为变量名称;如果实际上存在具有该名称的变量,则将其扩展为其值;如果不是,则删除包括周围%
符号的整个表达式。更糟糕的情况是在百分号之间出现冒号和/或等号,因为这样表示子字符串替换语法(有关详细信息,请参阅set /?
)。
当然,您只需在代码中用%
替换每个%%
符号,例如call :findMostRecentFile "!fullFolderPath:%%=%%%%!" "%~3"
(每个%
加倍,因为%%
制作一个文字%
)。但是有更多字符可能会导致麻烦,例如感叹号!
,因为您已启用延迟变量扩展(因此与%
相同的问题适用)或^
,{{ 1}},&
,(
,也可能出现在路径中,还有)
,<
,>
和|
。通过使用延迟扩展("
)来避免参数扩展(%1
)以及立即变量扩展(%%
)可以防止脚本遇到所有这些问题。