在Windows命令提示符下退出尖括号
我需要将包含尖括号(<和>)的string回显到Windows机器上的文件中。 基本上我想要做的是以下几点:
echo some string < with angle > brackets >>myfile.txt
这不起作用,因为命令解释程序与尖括号混淆。 我可以像这样引用整个string:
echo "some string < with angle > brackets" >>myfile.txt
但是,我的文件里有双引号,我不想要。
转义括号ala unix也不起作用:
echo some string \< with angle \> brackets >>myfile.txt
想法?
出于某种原因,Windows转义字符是^。
echo some string ^< with angle ^> brackets >>myfile.txt
诚然,官方转义字符是^
,但要小心,因为有时你需要三个字符。 这只是有时 :
C:\WINDOWS> echo ^<html^> <html> C:\WINDOWS> echo ^<html^> | sort The syntax of the command is incorrect. C:\WINDOWS> echo ^^^<html^^^> | sort <html> C:\WINDOWS> echo ^^^<html^^^> ^<html^>
摆脱这种废话的一个窍门是使用非echo
的命令来执行输出并用双引号引起来:
C:\WINDOWS> set/p _="<html>" <nul <html> C:\WINDOWS> set/p _="<html>" <nul | sort <html>
请注意,这不会保留提示文本的前导空格。
有避免^
转义序列的方法。
你可以使用延迟扩展的variables。 下面是一个小批量脚本演示
@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
这些方法起作用的原因是因为延迟扩展和FORvariables扩展都是在<
, >
, &
, <
等特殊运算符之后发生的 , &&
, ||
被parsing。 请参阅Windows命令解释器(CMD.EXE)如何parsing脚本? 获取更多信息。
sin3.14指出,pipe道可能需要多次转义 。 例如:
echo ^^^<html^^^>|findstr .
pipe道需要多次转义的原因是因为pipe道的每一侧都是在新的CMD进程中执行的,因此该行会被多次parsing。 请参阅为什么在pipe道代码块内部延迟扩展失败? 为了解释Windowpipe道实现的许多尴尬的后果。
还有另一种方法来避免使用pipe道时的多次转义。 你可以明确地实例化你自己的CMD进程,并用引号保护单个转义:
cmd /c "echo ^<html^>"|findstr .
如果您想使用延迟扩展技术来避免转义,那么还有更多的惊喜(如果您是CMD.EXEdevise专家,您可能不会感到惊讶,但是没有官方的MicroSoft文档可以解释这个问题)
请记住,pipe道的每一侧都在其自己的CMD.EXE进程中执行,但该进程不会inheritance延迟扩展状态 – 它默认为OFF。 因此,您必须明确地实例化您自己的CMD.EXE进程并使用/ V:ON选项启用延迟扩展。
@echo off setlocal disableDelayedExpansion set "line=<html>" cmd /v:on /c echo !test!|findstr .
请注意,父批处理脚本中的延迟扩展是closures的。
但是,如果在父脚本中启用了延迟扩展,那么所有地狱都会打散。 以下不起作用:
@echo off setlocal enableDelayedExpansion set "line=<html>" REM - the following command fails cmd /v:on /c echo !test!|findstr .
问题是, !test!
在父脚本中展开,所以新的CMD过程试图parsing不受保护的<
和>
。
你可以逃脱!
,但这可能会变得棘手,因为这取决于是否!
是否被引用。
如果没有引用,则需要双重转义:
@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 .
但有一个令人惊讶的技巧,可以避免所有的转义 – 封闭pipe道的左侧,防止父脚本扩大!test!
过早:
@echo off setlocal enableDelayedExpansion set "line=<html>" (cmd /v:on /c echo !test!)|findstr .
但是,我想即使这不是免费的午餐,因为批量parsing器在使用括号时最后会引入一个额外的(也许是不需要的)空间。
Aint批处理脚本的乐趣;-)
为了在Windows上使用特殊字符(例如'>'),需要在它之前放置一个特殊的转义字符。
例如
echo A->B
将不会工作,因为'>'必须被'^'转义:
echo A-^>B
另请参阅转义序列 。
有一个短的batch file,它打印一组基本的特殊字符及其转义序列。
转义括号ala unix也不起作用:
用angular度\>括号>> myfile.txt回显一些string\ <
反斜杠将被视为绝对path名的开始。
您也可以使用双引号来转义特殊字符…
echo some string "<" with angle ">" brackets >>myfile.txt