【问题标题】:Escape angle brackets in a Windows command prompt在 Windows 命令提示符中转义尖括号
【发布时间】:2010-09-20 01:49:09
【问题描述】:

我需要将包含尖括号()的字符串回显到 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

想法?

【问题讨论】:

  • 引号也将被回显。

标签: windows cmd escaping


【解决方案1】:

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

例如

echo A->B

因为 '>' 必须被 '^' 转义,所以不会起作用:

 echo A-^>B

另见escape sequences

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

【讨论】:

    【解决方案2】:

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

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

    @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 变量扩展都发生在 &lt;&gt;&amp;|&amp;&amp;|| 等特殊运算符被解析之后。请参阅How does the Windows Command Interpreter (CMD.EXE) parse scripts? 了解更多信息。


    sin3.14 points out that pipes may require multiple escapes。例如:

    echo ^^^<html^^^>|findstr .
    

    管道需要多次转义的原因是管道的每一端都在一个新的 CMD 进程中执行,因此该行被多次解析。请参阅Why does delayed expansion fail when inside a piped block of code?,了解 Window 管道实现的许多尴尬后果。

    使用管道时还有另一种方法可以避免多次转义。您可以显式实例化您自己的 CMD 进程,并用引号保护单转义:

    cmd /c "echo ^<html^>"|findstr .
    

    如果你想使用延迟扩展技术来避免转义,那么还有更多的惊喜(如果你是 CMD.EXE 设计方面的专家,你可能不会感到惊讶,但没有官方文档说明这玩意儿)

    请记住,管道的每一侧都在其自己的 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进程试图解析未受保护的&lt;&gt;

    您可以转义 !,但这可能会很棘手,因为这取决于 ! 是否被引用。

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

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

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

    批处理脚本不好玩;-)

    【讨论】:

      【解决方案3】:

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

      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>
      

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

      【讨论】:

      • 请参阅my answer 的第二部分,了解为什么管道需要多次转义。
      • 三个^^^也是在Azure DOS/Kudu控制台中转义命令所需要的。
      • 我发现当您想通过 Azure CLI 在 Azure 密钥库中存储包含尖括号的值时,确实需要这样做。
      【解决方案4】:

      你也可以使用双引号来转义特殊字符...

      echo some string "<" with angle ">" brackets >>myfile.txt
      

      【讨论】:

      • 那行不通。 echo some string "&lt;" with angle "&gt;" brackets &gt;&gt;con 导致: some string "" 括号 但 OP 想要 some string 括号
      【解决方案5】:

      转义括号 ala unix 不会 要么工作:

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

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

      【讨论】:

      • 相对于当前驱动器号的绝对路径名... ;)
      • 反斜杠不被认为是 echo 命令文本中绝对路径名的开头——它只是在您发送它的任何地方都会通过管道传输的纯文本。 -- echo \ 例如按预期工作。 -- 但是,是的,“\”对于命令行转义字符来说是一个错误的选择,因为每个需要路径或文件名的命令/程序都必须输入 `\`。
      • 这个答案不能解决这个模糊不清的问题
      【解决方案6】:

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

      echo some string ^< with angle ^> brackets >>myfile.txt
      

      【讨论】:

      • 嗯,反斜杠用于路径名,双引号用于包裹有空格的文件名,所以剩下的字符选择不多。
      • 这也适用于其他字符,如 & 符号,谢谢。
      • 效果很好! echo some string ^&lt; with angle ^&gt; brackets &gt;&gt;con 导致:一些字符串 括号
      • 都是因为原始的 pc-dos 使用反斜杠来表示路径和向后兼容性。
      • 我怀疑这不是随机的。我的猜测是他们想使用一个不太可能出现在普通文本中的字符,这样它就不会导致容易避免但不需要的字符转义。
      猜你喜欢
      • 2011-12-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-08
      • 2021-05-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多