我非常擅长为Windows编写批处理脚本,但即使在这些年后如何正确地逃避字符也让我感到困惑。在尝试找出正确的方法来逃避正则表达式以便与sed一起使用时,这一点尤其困难。有什么工具可以帮助我吗?也许某些东西允许我粘贴在“普通”字符串中并且它会吐出该字符串的正确转义版本?
更新:我不愿意举个例子,因为我没有找到如何逃避一个特定字符串的答案。我也不是在寻找适合某个特定应用的解决方案。我正在寻找一种工具,它可以帮助我为每个我需要逃脱的字符串获取正确的转义语法,无论从命令行使用什么工具。
据说我真正想要的正则表达式是
(^.*)(Form Product=")([^"]*") FormType="[^"]*" FormID="([0-9][0-9]*)".*$
获取真正的正则表达式(即就BATCH而言未转义)并将其包含在某些sed语法中,例如ssed "s@ --- Insert escaped regex here --- @http://psph/\1/\2@g" "%~1"
,最后将其转义...再次,是否有任何工具可以帮助转义任何在BATCH命令行上使用的字符串?
P.S。 BATCH的逃避语法有很多例外,我甚至会选择一个好的备忘单。
答案 0 :(得分:46)
经Batch files - Escape Characters Rob van der Woude's Scripting Pages site页面Windows (and DOS) batch file character escaping is complicated页面的作者许可改编。
{{3}}:
就像宇宙一样,如果任何人 完全理解批处理,那么语言将立即被无限怪异和更复杂的自身版本所取代。这显然至少发生过一次;)
%
可以转义为%%
- “并非总是需要[在双引号字符串中进行转义],只需尝试”
这些字符“在双引号字符串中可能并不总是需要[转义],但它不会受到伤害”:
^
&
<
>
|
'
“仅在[{1}}”主题中“需要[转义]”(即在括号之间),除非 FOR /F
被使用“
backq
“仅在[{1}}”主题中“需要[转义]”(即在括号之间),如果使用 `
则
这些字符“仅在[{1}}”主题中“必须[转义]”(即在括号内),偶数在双引号字符串中“:
FOR /F
backq
FOR /F
,
;
=
必须被转义(
。
)
搜索模式中的双重双引号 !
→^^!
find
正则表达式"
""
findstr
\
[
]
"
Rob在这个问题上进一步评论(通过与我自己的电子邮件通信):
至于答案,我担心混乱比原来的海报更难实现:转义括号的要求还取决于代码块内的字符串是不是!
我想一个自动化工具可以在每个角色之前插入插入符号,然后将所有百分号加倍 - 如果字符串被双引号,它仍然会失败!
此外,各个程序负责解析它们的命令行参数,因此需要一些转义,例如,对于.
或*
,可能是由于批处理脚本中调用的特定程序。
答案 1 :(得分:5)
批处理的转义字符是插入符号(^
)。如果要在脚本中包含任何管道字符,则需要在字符前加上插入符号:
:: Won't work:
@echo Syntax: MyCommand > [file]
:: Will work:
@echo Syntax: MyCommand ^> [file]
答案 2 :(得分:1)
您可以简单地使用外部文件作为sed的输入。
或者直接批量使用字符串,最好使用延迟扩展。
setlocal DisableDelayedExpansion
set "regEx=s/^#*$/""/g"
setlocal EnableDelayedExpansion
sed !regEx! file.txt
编辑:如何使用未经修改的字符串批量
这使用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
答案 3 :(得分:0)
保留所有命令行参数的简单解决方案是使用%*
:它从第一个命令行参数开始返回整个命令行(在Windows NT 4中,%*
还包括所有前导空格)并排除任何输出重定向。