在Windows批处理文件中回显确切的字符串? [英] Echo exact string in windows batch file?

查看:111
本文介绍了在Windows批处理文件中回显确切的字符串?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试回显存储在变量中的字符串,但似乎需要大量的转义。我正在尝试使用以下代码:

  setlocal EnableDelayedExpansion 
@echo off
setgrass = @ ##&!$ ^&%**(&)
echo!grass!

我想回应变量 grass 所以我在输出中看到一个 @ ##&!$ ^&%**(&)。应该做什么谢谢!

解决方案

echo!grass!将始终回显当前值逐字,不需要任何逃脱。你的问题是,价值不是你认为的!当您尝试设置值时,会出现问题。



设置值的正确转义序列是

  setgrass = @ ##& ^!$ ^^& %% **(&)

现在解释。您需要的信息被隐藏在如何Windows Command Interpreter(CMD.EXE)解析脚本吗?但这是有点难以追随。



您有两个问题:



1)每次要解析该行时,都必须以 %% 转义。报价的存在或不存在没有区别。延迟扩张状态也没有区别。

  set pct =%
:: pct未定义

set pct = %%
:: pct =%

调用set pct = %%
:: pct未定义,因为该行由于CALL而被解析两次

调用set pct = %%%%
:: pct =%

2)每当它被延迟扩展阶段解析时,必须将直接转义为 ^!的解析器。如果一个行在延迟展开期间的任何地方包含,则必须将 ^ 文字转义为 ^^ 。但是,对于解析器的特殊字符阶段, ^ 也必须被引用或转义为 ^^ 。这可能会因为CALL将任何 ^ 字符加倍而变得更为复杂。 (对不起,很难描述问题,解析器很复杂!)

  setlocal disableDelayedExpansion 

set test = ^^
:: test = ^

settest = ^
:: test = ^

call set test = ^^
:: test = ^
::第一遍 - ^^变成^
:: CALL双打^,所以我们回到^^
:: 2nd通过 - ^^成为^

调用集test = ^
:: test = ^^因为CALL倍增。没有什么可以阻止这个。

设置test = ^ ...!
:: test = ^ ...!
::!延迟扩展被禁用时对^没有影响

setlocal enableDelayedExpansion

settest = ^
:: test = ^
:: there没有 !在线上,所以没有必要逃避引用^。

设置test = ^!
:: test =!

set test = ^^!
:: test =!
::!必须被转义,然后无引号的转义必须被转义

set var = hello
settest =!var!^^ ^!
:: test = hello ^!
:: quoted ^ literal必须被转义,因为!出现在行

set test =!var! ^^^^ ^^!
:: test = hello ^!
:: ^ literal的无引号转义本身必须被转义
::同样如此!文字

调用set test =!var! ^^^^ ^^!
:: test = hello ^!
::延迟扩展阶段发生在第一次通过
:: CALL倍增保护第二遍中的无引号^文字

调用集test =!var!^^ ^!
:: test = hello ^^!
::再次,当它通过CALL
::加倍>

I'm trying to echo a string stored in a variable but it seems to require a lot of escaping. I'm trying with the following code:

setlocal EnableDelayedExpansion
@echo off
set "grass=@##&!$^&%**(&)"
echo !grass!

I want to echo the variable grass verbatim so I see a @##&!$^&%**(&) in the output. What should be done? Thanks!

解决方案

echo !grass! will always echo the current value verbatim, without the need of any escaping. Your problem is, the value is not what you think it is! The problem is occurring when you are trying to SET the value.

The correct escape sequence to set your value is

set "grass=@##&^!$^^&%%**(&)"

And now for the explanation. The information you need is buried in How does the Windows Command Interpreter (CMD.EXE) parse scripts?. But it is a bit hard to follow.

You have two problems:

1) % must be escaped as %% for each time the line will be parsed. The presence or absence of quotes makes no difference. The delayed expansion state also makes no difference.

 set pct=%
 :: pct is undefined

 set pct=%%
 :: pct=%

 call set pct=%%
 :: pct is undefined because the line is parsed twice due to CALL

 call set pct=%%%%
 :: pct=%

2) A ! literal must be escaped as ^! whenever it is parsed by the delayed expansion phase of the parser. If a line contains ! anywhere within it during delayed expansion, then a ^ literal must be escaped as ^^. But the ^ must also be either quoted or escaped as ^^ for the special character phase of the parser. This can be further complicated by the fact that a CALL will double up any ^ characters. (Sorry, it is very difficult to describe the problem, and the parser is complicated!)

setlocal disableDelayedExpansion

set test=^^
:: test=^

set "test=^"
:: test=^

call set test=^^
:: test=^
:: 1st pass - ^^ becomes ^
:: CALL doubles ^, so we are back to ^^
:: 2nd pass - ^^ becomes ^

call set "test=^"
:: test=^^ because of CALL doubling. There is nothing that can prevent this.

set "test=^...!"
:: test=^...!
:: ! has no impact on ^ when delayed expansion is disabled

setlocal enableDelayedExpansion

set "test=^"
:: test=^
:: There is no ! on the line, so no need to escape the quoted ^.

set "test=^!"
:: test=!

set test=^^!
:: test=!
:: ! must be escaped, and then the unquoted escape must be escaped

set var=hello
set "test=!var! ^^ ^!"
:: test=hello ^ !
:: quoted ^ literal must be escaped because ! appears in line

set test=!var! ^^^^ ^^!
:: test=hello ^ !
:: The unquoted escape for the ^ literal must itself be escaped
:: The same is true for the ! literal

call set test=!var! ^^^^ ^^!
:: test=hello ^ !
:: Delayed expansion phase occurs in the 1st pass only
:: CALL doubling protects the unquoted ^ literal in the 2nd pass

call set "test=!var! ^^ ^!"
:: test=hello ^^ !
:: Again, there is no way to prevent the doubling of the quoted ^ literal
:: when it is passed through CALL

这篇关于在Windows批处理文件中回显确切的字符串?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆