windows 批量字符转义
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6828751/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Batch character escaping
提问by HairOfTheDog
I'm fairly proficient at writing Batch scripts for Windows, but even after all these years how to correctly escape characters puzzles me. It's especially difficult when trying figure out the correct way to escape a regular expression for use with sed. Is there any tool that can help me? Perhaps something that allows me to paste in a "normal" string and it spits out the correctly escaped version of that string?
我相当精通为 Windows 编写批处理脚本,但即使经过这么多年,如何正确转义字符也让我感到困惑。在尝试找出转义正则表达式以与 sed 一起使用的正确方法时尤其困难。有什么工具可以帮助我吗?也许某些东西可以让我粘贴“正常”字符串并吐出该字符串的正确转义版本?
Update:I'm reluctant to give an example because I'm not looking for an answer on how to escape one specific string. I'm also not looking for a solution that will work for one specific app. I'm looking for a tool that will help me get the escape syntax correct for every string I ever need to escape no matter what tool might be consuming it from the command line.
更新:我不愿意举个例子,因为我不是在寻找关于如何转义一个特定字符串的答案。我也不是在寻找适用于某个特定应用程序的解决方案。我正在寻找一种工具,它可以帮助我为我需要转义的每个字符串获得正确的转义语法,无论什么工具可能从命令行使用它。
That being said the regex I really want is
话虽如此,我真正想要的正则表达式是
(^.*)(Form Product=")([^"]*") FormType="[^"]*" FormID="([0-9][0-9]*)".*$
Take that true regex (i.e. unescaped as far as BATCH is concerned) and wrap it in some sed syntax such as ssed "s@ --- Insert escaped regex here --- @http://psph/\1/\2@g" "%~1"
and finally escape it... Again, is there any tool that can assist in escaping any string for use on the BATCH command line?
采用真正的正则表达式(即就 BATCH 而言未转义)并将其包装在一些 sed 语法中,例如ssed "s@ --- Insert escaped regex here --- @http://psph/\1/\2@g" "%~1"
并最终转义它......同样,是否有任何工具可以帮助转义任何字符串以在 BATCH 命令行上使用?
p.s. There are so many exceptions to BATCH's escaping syntax that I'll even settle for a good cheat sheet.
ps BATCH 的转义语法有很多例外,我什至会选择一个好的备忘单。
回答by Kenny Evitt
This is adapted with permission of the author from the page Batch files - Escape Characterson Rob van der Woude's Scripting Pages site.
这适用于与笔者从页面的权限批处理文件-转义字符上抢的van der Woude的脚本页的网站。
TLDR
TLDR
Windows (and DOS) batch file character escaping is complicated:
Much like the universe, if anyone ever doesfully come to understand Batch then the language will instantly be replaced by an infinitely weirder and more complex version of itself. This has obviously happened at least once before ;)
就像宇宙中,如果有谁不完全明白过来批那么这种语言会立即通过自身无限离奇,更复杂的版本替换。这显然至少发生过一次;)
Percent Sign %
百分号 %
%
can be escaped as %%
– "May not always be required [to be escaped] in doublequoted strings, just try"
%
可以转义为%%
-“在双引号字符串中可能并不总是需要[转义],只需尝试”
Generally, Use a Caret ^
通常,使用插入符号 ^
These characters "may not always be required [to be escaped] in doublequoted strings, but it won't hurt":
这些字符“在双引号字符串中可能并不总是需要 [转义],但它不会受到伤害”:
^
&
<
>
|
^
&
<
>
|
Example:echo a ^> b
to print a > b
on screen
示例:在屏幕上echo a ^> b
打印a > b
'
is "required [to be escaped] only in the FOR /F
"subject" (i.e. between the parenthesis), unlessbackq
is used"
'
仅在FOR /F
“主题”(即括号之间)中需要[转义] ,除非backq
使用”
`
is "required [to be escaped] only in the FOR /F
"subject" (i.e. between the parenthesis), ifbackq
is used"
`
是“仅在FOR /F
“主题”(即括号之间)中需要[转义] ,如果backq
使用”
These characters are "required [to be escaped] only in the FOR /F
"subject" (i.e. between the parenthesis), evenin doublequoted strings":
这些字符“仅在FOR /F
“主题”中(即在括号之间)才需要[转义] ,即使在双引号字符串中也是如此”:
,
;
=
(
)
,
;
=
(
)
Double Escape Exclamation Points when Using Delayed Variable Expansion
使用延迟变量扩展时的双转义感叹号
!
must be escaped ^^!
when delayed variable expansion is active.
!
^^!
当延迟变量扩展处于活动状态时必须转义。
Double Double-Quotes in find
Search Patterns
find
搜索模式中的双双引号
"
→ ""
"
→ ""
Use a Backslash in findstr
Regex Patterns
在正则findstr
表达式模式中使用反斜杠
\
[
]
"
.
*
?
\
[
]
"
.
*
?
Also
还
Rob commented further on this question (via email correspondence with myself):
Rob 进一步评论了这个问题(通过与我自己的电子邮件通信):
As for the answer, I'm afraid the chaos is even worse than the original poster realizes: requirements for escaping parentheses also depend on the string being inside a code block or not!
I guess an automated tool could just insert a caret before every character, then doubling all percent signs - and it would still fail if the string is doublequoted!
至于答案,恐怕比原发帖者意识到的更混乱:转义括号的要求还取决于字符串是否在代码块内!
我猜一个自动化工具可以在每个字符前插入一个插入符号,然后将所有百分号加倍 - 如果字符串被双引号,它仍然会失败!
Further, individual programs are responsible for parsing their command line arguments so some of the escaping required for, e.g. for sed
or ssed
, may be due to the specific programs called in the batch scripts.
此外,个别程序负责解析它们的命令行参数,因此某些需要的转义,例如 forsed
或ssed
,可能是由于批处理脚本中调用的特定程序。
回答by Patrick Cuff
The escape character for batch is the caret (^
). If you want to include any of the pipeline characters in your script you need to prefix the character with the caret:
批处理的转义字符是插入符号 ( ^
)。如果要在脚本中包含任何管道字符,则需要在字符前加上脱字符:
:: Won't work:
@echo Syntax: MyCommand > [file]
:: Will work:
@echo Syntax: MyCommand ^> [file]
回答by jeb
You could simply use an external file as input for sed.
您可以简单地使用外部文件作为 sed 的输入。
Or using strings directly in batch, it's a good idea to use the delayed expansion.
或者直接批量使用字符串,使用延迟扩展是个好主意。
setlocal DisableDelayedExpansion
set "regEx=s/^#*$/""/g"
setlocal EnableDelayedExpansion
sed !regEx! file.txt
EDIT: How to use unmodifiedstrings with a batch
编辑:如何在批处理中使用未修改的字符串
This uses findstr to get the string directly from the batch and return it into a result-variable.
So you can use the sed-string as is.
这使用 findstr 直接从批处理中获取字符串并将其返回到结果变量中。
因此,您可以按原样使用 sed-string。
@echo off
setlocal
REM SedString1#(^.*)(Form Product=")([^"]*") FormType="[^"]*" FormID="([0-9][0-9]*)".*$
call :GetSEDString result SedString1
setLocal EnableDelayedExpansion
echo the sedString is !result!
sed !result!
goto :eof
:GetSEDString <resultVar> <searchName>
:: Search the own batch file for <searchName> in a line with "REM <searchName>#"
:: Return all after the "#" without any modification
setLocal DisableDelayedExpansion
for /f "usebackq tokens=* delims=" %%G in (`findstr /n /c:"REM %~2#" "%~f0"`) do (
set "str=%%G"
)
setLocal EnableDelayedExpansion
set "str=!str:*#=!"
for /F "delims=" %%A in ("!str!") DO (
endlocal
endlocal
set "%~1=%%A"
goto :eof
)
goto :eof
回答by Pino
A simple solution to preserve all command line arguments is to use %*
: it returns the whole command line starting at the first command line argument (in Windows NT 4, %*
also includes all leading spaces) and excluding any output redirection.
保留所有命令行参数的一个简单解决方案是使用%*
:它返回从第一个命令行参数开始的整个命令行(在 Windows NT 4 中,%*
还包括所有前导空格)并排除任何输出重定向。