批量字符转义

时间:2011-07-26 10:37:23

标签: windows scripting batch-file

我非常擅长为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的逃避语法有很多例外,我甚至会选择一个好的备忘单。

4 个答案:

答案 0 :(得分:46)

Batch files - Escape Characters Rob van der Woude's Scripting Pages site页面Windows (and DOS) batch file character escaping is complicated页面的作者许可改编。

TLDR

{{3}}:

  
    

就像宇宙一样,如果任何人 完全理解批处理,那么语言将立即被无限怪异和更复杂的自身版本所取代。这显然至少发生过一次;)

  

百分号

%可以转义为%% - “并非总是需要[在双引号字符串中进行转义],只需尝试”

通常,使用Caret

这些字符“在双引号字符串中可能并不总是需要[转义],但它不会受到伤害”:

  • ^
  • &
  • <
  • >
  • |

'“仅在[{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中,%*还包括所有前导空格)并排除任何输出重定向。