web-dev-qa-db-fra.com

Caractère de lot s'échappant

Je maîtrise assez bien l'écriture de scripts batch pour Windows, mais même après toutes ces années, il est difficile de comprendre comment échapper correctement aux caractères. Il est particulièrement difficile d’essayer de trouver la bonne façon d’échapper à une expression régulière à utiliser avec sed. Y at-il un outil qui peut m'aider? Peut-être que quelque chose qui me permet de coller une chaîne "normale" et crache la version correctement échappée de cette chaîne?

Mise à jour: Je suis réticent à donner un exemple car je ne cherche pas de réponse pour échapper à une chaîne spécifique. Je ne cherche pas non plus de solution qui convienne à une application spécifique. Je cherche un outil qui m'aide à obtenir la syntaxe d'échappement correcte pour chaque chaîne que je dois échapper, quel que soit l'outil utilisé pour la consommer depuis la ligne de commande. 

Cela étant dit, la regex que je veux vraiment est 

(^.*)(Form Product=")([^"]*") FormType="[^"]*" FormID="([0-9][0-9]*)".*$

Prenez cette vraie expression rationnelle (c'est-à-dire non échappé en ce qui concerne BATCH) et emballez-la dans une syntaxe sed telle que ssed "s@ --- Insert escaped regex here --- @http://psph/\1/\2@g" "%~1" et finalement échappez-la ... Encore une fois, existe-t-il un outil qui peut aider à échapper à toute chaîne utilisée dans la commande BATCH ligne? 

p.s. Il y a tellement d'exceptions à la syntaxe d'échappement de BATCH que je vais même me contenter d'un bon aide-mémoire.

30
HairOfTheDog

Le caractère d'échappement pour batch est le caret (^). Si vous souhaitez inclure l'un des caractères de pipeline dans votre script, vous devez le préfixer avec le curseur:

:: Won't work:
@echo Syntax: MyCommand > [file]

:: Will work:
@echo Syntax: MyCommand ^> [file]
5
Patrick Cuff

Vous pouvez simplement utiliser un fichier externe comme entrée pour sed. 

Ou en utilisant des chaînes directement en batch, c'est une bonne idée d'utiliser l'extension retardée.

setlocal DisableDelayedExpansion
set "regEx=s/^#*$/""/g"
setlocal EnableDelayedExpansion
sed !regEx! file.txt

EDIT: Comment utiliser les chaînes non modifiées avec un lot

Ceci utilise findstr pour obtenir la chaîne directement à partir du lot et la renvoyer dans une variable de résultat.
Vous pouvez donc utiliser la chaîne sed telle quelle.

@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
1
jeb

Une solution simple pour conserver tous les arguments de la ligne de commande consiste à utiliser %*: il renvoie la ligne de commande complète à partir du premier argument de la ligne de commande (dans Windows NT 4, %* inclut également tous les espaces de début), en excluant toute redirection de sortie.

0
Pino