Batch file 如何将参数传递到包含%的批处理文件,而不传递它';破坏';?
问题 在主批处理文件中,从.txt文件中提取值(并将Batch file 如何将参数传递到包含%的批处理文件,而不传递它';破坏';?,batch-file,Batch File,问题 在主批处理文件中,从.txt文件中提取值(并将设置为该批处理文件中变量的值)。这些值可能每个都包含%字符 这些都是从.txt文件中读取的,没有任何问题。但是,当值包含%字符的变量传递给第二个批处理文件时,第二个批处理文件会将任何%字符解释为变量扩展。(注意:第二批文件没有控制权。) 示例 echo %PERCENTVARIABLE% 输出:I%LOVE%CHARACTERS% 当传递到第二个文件并进行回显时,将(可能)变成IPERCENT,因为它将%LOVE%和%CHARACTERS%解
设置为该批处理文件中变量的值)。这些值可能每个都包含%
字符
这些都是从.txt文件中读取的,没有任何问题。但是,当值包含%
字符的变量传递给第二个批处理文件时,第二个批处理文件会将任何%
字符解释为变量扩展。(注意:第二批文件没有控制权。)
示例
echo %PERCENTVARIABLE%
输出:I%LOVE%CHARACTERS%
当传递到第二个文件并进行回显时,将(可能)变成IPERCENT
,因为它将%LOVE%
和%CHARACTERS%
解释为未设置的变量
研究
我找到了在批处理文件中查找和替换字符串中元素的语法,因为我认为可以用%%
字符替换%%
字符以转义它。但是我不能让它工作
语法是-
set string=This is my string to work with.
set string=%string:work=play%
echo %string%
输出将是这是我要玩的字符串。
问题
是否可以使用查找和替换语法转义%
字符
在变量中?(如果没有,还有别的办法吗?)
是否建议这样做?(使用这些转义字符是否会导致第二批处理文件中出现我们无法控制的问题?)
如果上述方法不可行,是否有其他方法处理此问题
可能是
input.txt
batch1.bat
没有简单的规则可以适用于所有情况
有几个问题使得在参数中使用字符串文字变得困难:
有毒字符如&
,|
等必须转义或引用。逃跑是困难的,因为它可能会混淆逃脱多少次。因此建议通常引用字符串
令牌分隔符,如
,
,=
,代码>和,
不能包含在参数值中,除非它被引用
对脚本的调用将使任何引用的%
字符翻倍,并且没有办法防止这种情况发生。在没有调用的情况下执行脚本不会使%
字符加倍。但若一个脚本调用另一个脚本并期望返回控制,那个么必须使用该调用
因此,我们有一个第22条军规:一方面,我们希望引用参数来防止有害字符和空格(标记分隔符)。但为了保护百分比,我们不想引用
可靠地传递字符串文本而不担心值损坏的唯一可靠方法是通过环境变量通过引用传递它们
要传递的值应存储在环境值中。引号和/或转义符和/或倍增百分比用于获取值中的必要字符,但它非常易于管理
变量的名称作为参数传入
脚本通过延迟扩展访问该值。例如,如果第一个参数是包含该值的变量的名称,则它将作为!%访问1!代码>。必须先启用延迟扩展,然后才能使用该语法-只需发出setlocal enableDelayedExpansion
延迟扩展的好处在于,在扩展变量时,您永远不必担心有毒字符、空格或百分比的损坏
下面的示例显示了如何将以下字符串文本传递给子例程
“这个&那个!”&另一件事代码>
@echo关闭
setlocal enableDelayedExpansion
设置“parm1=”^This^和that^^!“&另一件事^!”
在调用之前回显值!parm1!
调用:testparm1
退出/b
:测试
回显调用后的值为!%1.
--输出--
调用前的值是“This&that!”&另一个!
调用后的值是“This&that!”&另一个!
但是你声明你对第二个脚本没有控制权。因此,上述优雅的解决方案不适用于您
如果您要显示第二个脚本的代码,并准确显示您试图传递的值,那么我可能能够给出一个在这种孤立情况下有效的解决方案。但有些值是无法传递的,除非延迟扩展与变量名一起使用。(实际上,另一个选项是将值放入文件中并从文件中读取值,但这也需要更改第二个脚本)如果任务适合操作,dbenham可以使用jrepl.bat
处理该文件。jrepl使用jscript并可以处理有毒字符
@foxidrive您知道这将如何直接影响第一个脚本中变量值的使用吗?变量可能会在第一个脚本中使用(我们有控件),也会通过“传递到第二个文件”传递到第二个脚本(不在我们的控件中),您的意思是使用调用调用调用它。。。问题是由调用
和引入第二个%
解析阶段引起的;那么,通过call
而不是通过值来传递变量名呢?我的意思是,比如:call batch.bat STRING
(而不是call batch.bat“%STRING%”
),然后使用set“ARG=%%1”
和call set“ARG=%%ARG%%”
(而不是set“ARG=%%1”
),或者在启用时,设置“ARG=!%%1!”
?这将隐藏所述第二个解析阶段的字符串…这对%
有效,但对^
无效
I%LOVE%PERCENT%CHARACTERS%
@echo off
setlocal enableDelayedExpansion
set/P var=<input.txt
echo(In batch 1 var content: %var%
set "var=!var:%%=%%%%!"
call batch2.bat "%var%"
endlocal
exit/B
@echo off
set "var=%~1"
echo(In batch 2 var content: %var%
exit/B
@echo off
setlocal enableDelayedExpansion
set "parm1="^<%%^|,;^^^^^> This ^& that^^!" & the other thing^! <%%|,;^^^>"
echo The value before CALL is !parm1!
call :test parm1
exit /b
:test
echo The value after CALL is !%1!
The value before CALL is "<%|,;^> This & that!" & the other thing! <%|,;^>
The value after CALL is "<%|,;^> This & that!" & the other thing! <%|,;^>