100

我需要将包含尖括号(< 和 >)的字符串回显到 Windows 机器上的文件中。基本上我想做的是以下几点:
echo some string < with angle > brackets >>myfile.txt

这不起作用,因为命令解释器与尖括号混淆了。我可以像这样引用整个字符串:
echo "some string < with angle > brackets" >>myfile.txt

但是后来我的文件中有我不想要的双引号。

转义方括号 ala unix 也不起作用:
echo some string \< with angle \> brackets >>myfile.txt

想法?

4

6 回答 6

178

出于某种原因,Windows 转义字符是 ^。

echo some string ^< with angle ^> brackets >>myfile.txt
于 2008-10-30T20:10:40.067 回答
26

诚然,官方转义字符是^,但要小心,因为有时您需要三个 ^字符。这只是有时

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>

请注意,这不会保留提示文本上的前导空格。

于 2012-07-21T17:04:59.307 回答
9

有一些方法可以避免^转义序列。

您可以使用延迟扩展的变量。下面是一个小批量脚本演示

@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 进程中执行,但该进程不会继承延迟扩展状态 - 它默认为 OFF。因此,您必须显式实例化您自己的 CMD.EXE 进程并使用 /V:ON 选项来启用延迟扩展。

@echo off
setlocal disableDelayedExpansion
set "line=<html>"
cmd /v:on /c echo !test!|findstr .

请注意,延迟扩展在父批处理脚本中处于关闭状态。

但是,如果在父脚本中启用了延迟扩展,那么所有的地狱都会崩溃。以下不起作用

@echo off
setlocal enableDelayedExpansion
set "line=<html>"
REM - the following command fails
cmd /v:on /c echo !test!|findstr .

问题是!test!在父脚本中展开,所以新的 CMD 进程试图解析 unprotected<>.

您可以逃避!,但这可能会变得棘手,因为这取决于是否!引用了 。

如果没有引用,则需要双重转义:

@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 .

但我想即使这样也不是免费的午餐,因为批处理解析器在使用括号时会在末尾引入一个额外的(也许是不需要的)空间。

不是批处理脚本的乐趣;-)

于 2014-09-25T14:39:29.917 回答
3

为了使用特殊字符,例如 Windows 上带有 echo 的“>”,您需要在其前面放置一个特殊的转义字符。

例如

echo A->B

因为 '>' 必须被 '^' 转义,所以将无法工作:

 echo A-^>B

另请参阅转义序列在此处输入图像描述

有一个简短的批处理文件,它打印一组基本的特殊字符及其转义序列。

于 2015-11-23T13:42:52.843 回答
0

转义方括号 ala unix 也不起作用:

回显一些字符串 \< 带角 \> 括号 >>myfile.txt

反斜杠将被视为绝对路径名的开始。

于 2008-10-30T20:30:47.343 回答
-3

您还可以使用双引号来转义特殊字符...

echo some string "<" with angle ">" brackets >>myfile.txt
于 2011-03-28T06:58:15.307 回答