我需要将包含尖括号(<和>)的字符串回显到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
想法?
Tim*_*son 166
由于某种原因,Windows转义字符是^.
echo some string ^< with angle ^> brackets >>myfile.txt
Run Code Online (Sandbox Code Playgroud)
sin*_*.14 23
确实,官方的逃脱角色是^
,但要小心,因为有时你需要三个 ^
角色.这只是有时候:
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^>
Run Code Online (Sandbox Code Playgroud)
这个废话的一个技巧是使用除echo
输出之外的命令并使用双引号引用:
C:\WINDOWS> set/p _="<html>" <nul
<html>
C:\WINDOWS> set/p _="<html>" <nul | sort
<html>
Run Code Online (Sandbox Code Playgroud)
请注意,这不会保留提示文本上的前导空格.
有一些方法可以避免^
转义序列.
您可以使用具有延迟扩展的变量.下面是一个小批量脚本演示
@echo off
setlocal enableDelayedExpansion
set "line=<html>"
echo !line!
Run Code Online (Sandbox Code Playgroud)
或者你可以使用FOR/F循环.从命令行:
for /f "delims=" %A in ("<html>") do @echo %~A
Run Code Online (Sandbox Code Playgroud)
或者从批处理脚本:
@echo off
for /f "delims=" %%A in ("<html>") do echo %%~A
Run Code Online (Sandbox Code Playgroud)
这些方法工作的原因是因为这两个延迟扩展和FOR变量扩展特种作业等之后发生<
,>
,&
,|
,&&
,||
被解析.请参阅Windows命令解释器(CMD.EXE)如何解析脚本?了解更多信息.
echo ^^^<html^^^>|findstr .
Run Code Online (Sandbox Code Playgroud)
管道需要多次转义的原因是管道的每一侧都在新的CMD过程中执行,因此该行被多次解析.请参阅为什么在管道代码块内部延迟扩展失败?解释Window的管道实现的许多尴尬后果.
使用管道时还有另一种避免多次转义的方法.您可以显式实例化您自己的CMD进程,并使用引号保护单个转义:
cmd /c "echo ^<html^>"|findstr .
Run Code Online (Sandbox Code Playgroud)
如果你想使用延迟扩展技术来避免逃逸,那么还有更多的惊喜(如果你是CMD.EXE设计方面的专家,你可能不会感到惊讶,但是没有正式的MicroSoft文档可以解释这些东西)
请记住,管的每一面在自己的CMD.EXE过程被执行,但这一过程不会不继承推迟扩张状态-它默认为关闭.因此,您必须显式实例化您自己的CMD.EXE进程并使用/ V:ON选项启用延迟扩展.
@echo off
setlocal disableDelayedExpansion
set "line=<html>"
cmd /v:on /c echo !test!|findstr .
Run Code Online (Sandbox Code Playgroud)
请注意,父批处理脚本中的延迟扩展为OFF.
但是如果在父脚本中启用了延迟扩展,那么所有地狱都会破裂.以下就不能正常工作:
@echo off
setlocal enableDelayedExpansion
set "line=<html>"
REM - the following command fails
cmd /v:on /c echo !test!|findstr .
Run Code Online (Sandbox Code Playgroud)
问题是,!test!
在父脚本扩展,所以新的CMD进程试图解析未受保护的<
和>
.
你可以逃脱!
,但这可能会变得棘手,因为它取决于是否!
引用.
如果没有引用,则需要双重转义:
@echo off
setlocal enableDelayedExpansion
set "line=<html>"
cmd /v:on /c echo ^^!test^^!|findstr .
Run Code Online (Sandbox Code Playgroud)
如果引用,则使用单个转义:
@echo off
setlocal enableDelayedExpansion
set "line=<html>"
cmd /v:on /c "echo ^!test^!"|findstr .
Run Code Online (Sandbox Code Playgroud)
但是有一个令人惊讶的技巧可以避免所有的转义 - 封闭管道的左侧会阻止父脚本!test!
过早地扩展:
@echo off
setlocal enableDelayedExpansion
set "line=<html>"
(cmd /v:on /c echo !test!)|findstr .
Run Code Online (Sandbox Code Playgroud)
但我想即使这不是免费的午餐,因为批处理解析器在使用括号时会在末尾引入额外的(可能不需要的)空间.
Aint批处理脚本乐趣;-)
归档时间: |
|
查看次数: |
40862 次 |
最近记录: |