有一些避免^
转义序列的方法。
您可以使用延迟扩展的变量。以下是小批量脚本演示
@echo off
setlocal enableDelayedExpansion
set "line=<html>"
echo !line!
或者,您可以使用FOR / F循环。从命令行:
for /f "delims=" %A in ("<html>") do @echo %~A
或从批处理脚本中:
@echo off
for /f "delims=" %%A in ("<html>") do echo %%~A
究其原因,这些方法的工作是因为特殊的运营商等之后都会出现延迟扩展和FOR变量扩展<
,>
,&
,|
,&&
,||
被解析。请参阅Windows命令解释器(CMD.EXE)如何解析脚本?有关更多信息。
sin3.14指出管道可能需要多次逸出。例如:
echo ^^^<html^^^>|findstr .
管道需要多次转义的原因是,管道的每一面都是在新的CMD流程中执行的,因此该行会被多次解析。请参阅为什么在管道代码块中延迟扩展失败?解释Window管道实现的许多尴尬后果。
使用管道时,还有另一种避免多次转义的方法。您可以显式实例化自己的CMD流程,并用引号保护单个转义:
cmd /c "echo ^<html^>"|findstr .
如果您想使用延迟扩展技术来避免转义,那么还会有更多的惊喜(如果您是CMD.EXE的设计专家,则可能并不感到惊讶,但是没有正式的MicroSoft文档可以解释这些问题)
请记住,管的每一面在自己的CMD.EXE过程被执行,但这一过程不会不继承延迟扩张状态-它默认为关闭。因此,您必须显式实例化自己的CMD.EXE进程,并使用/ V:ON选项启用延迟的扩展。
@echo off
setlocal disableDelayedExpansion
set "line=<html>"
cmd /v:on /c echo !test!|findstr .
请注意,在父批处理脚本中,延迟扩展为OFF。
但是,如果在父脚本中启用了延迟扩展,那么一切都将变得一团糟。以下就不能正常工作:
@echo off
setlocal enableDelayedExpansion
set "line=<html>"
REM - the following command fails
cmd /v:on /c echo !test!|findstr .
问题是!test!
在父脚本中进行了扩展,因此新的CMD进程试图解析不受保护的<
和>
。
您可以转义!
,但可能会很棘手,因为这取决于是否!
引用了。
如果未引用,则需要两次转义:
@echo off
setlocal enableDelayedExpansion
set "line=<html>"
cmd /v:on /c echo ^^!test^^!|findstr .
如果引用,则使用一个转义符:
@echo off
setlocal enableDelayedExpansion
set "line=<html>"
cmd /v:on /c "echo ^!test^!"|findstr .
但是,有一个令人惊讶的技巧可以避免所有转义-封闭管道的左侧可以防止父脚本!test!
过早扩展:
@echo off
setlocal enableDelayedExpansion
set "line=<html>"
(cmd /v:on /c echo !test!)|findstr .
但是我想那也不是免费的午餐,因为批处理解析器在使用括号时在末尾引入了一个额外的(可能是不需要的)空间。
Aint批处理脚本很有趣;-)