wake-up-neo.net

Chargenzeichen entkommen

Ich bin ziemlich gut darin, Batch-Skripte für Windows zu schreiben, aber selbst nach all den Jahren rätselt es mich, wie man Zeichen richtig entkommt. Es ist besonders schwierig, den richtigen Weg zu finden, um einem regulären Ausdruck für sed zu entgehen. Gibt es ein Werkzeug, das mir helfen kann? Vielleicht etwas, das mir erlaubt, eine "normale" Zeichenfolge einzufügen und die korrekt maskierte Version dieser Zeichenfolge ausspuckt?

Update: Ich möchte nur ein Beispiel geben, weil ich nicht nach einer Antwort suche, wie man eine bestimmte Zeichenfolge fluchtet. Ich bin auch nicht auf der Suche nach einer Lösung, die für eine bestimmte App funktioniert. Ich bin auf der Suche nach einem Tool, das mir dabei helfen wird, die Escape-Syntax für jeden String zu korrigieren, den ich je entziehen muss, unabhängig davon, welches Tool es von der Befehlszeile aus verwendet. 

Der Regex, den ich wirklich will, ist 

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

Nehmen Sie den richtigen Regex (dh in Bezug auf BATCH nicht maskiert) und wickeln Sie ihn in eine Sed-Syntax wie ssed "[email protected] --- Insert escaped regex here --- @http://psph/\1/\[email protected]" "%~1" ein, und entziehen Sie ihn schließlich Linie? 

p.s. Es gibt so viele Ausnahmen zu BATCHs flüchtiger Syntax, dass ich mich sogar mit einem guten Spickzettel zufrieden geben werde.

30
HairOfTheDog

Dies wird mit Erlaubnis des Autors von der Seite Batch-Dateien - Escape Characters auf Rob van der Woude's Scripting Pages Site angepasst.

TLDR

Windows (und DOS) Batch-Datei Zeichen Escape ist kompliziert :

Ähnlich wie im Universum wird die Sprache sofort durch eine unendlich seltsamere und komplexere Version von sich selbst ersetzt, wenn irgendjemand Batch vollständig versteht . Das ist offensichtlich schon mindestens einmal passiert;)

Prozentzeichen %

% kann als %% maskiert werden - "Muss nicht immer in doppelten Anführungszeichen angegeben werden, versuchen Sie es einfach."

Verwenden Sie im Allgemeinen ein Caret ^

Diese Zeichen "müssen nicht immer in doppelten Anführungszeichen angegeben werden, aber es tut nicht weh":

  • ^
  • &
  • <
  • >
  • |

Beispiel: echo a ^> b zum Ausdrucken von a > b auf dem Bildschirm

' ist "nur im Betreff" FOR /F erforderlich [zu maskieren] "(dh zwischen den Klammern), , sofern nicht backq wird verwendet "

` ist "nur im FOR /F" Betreff erforderlich [zu maskieren] "(dh zwischen den Klammern), wenn backq wird verwendet "

Diese Zeichen sind "nur im FOR /F" Betreff erforderlich "(dh zwischen den Klammern), sogar in Strings mit doppelten Anführungszeichen ":

  • ,
  • ;
  • =
  • (
  • )

Doppelte Escape-Ausrufezeichen bei Verwendung der verzögerten Variablenerweiterung

! muss mit Escape-Zeichen versehen werden ^^!, wenn die verzögerte Variablenerweiterung aktiv ist.

Double Double-Quotes in find Suchmustern

"""

Verwenden Sie einen Backslash in findstr Regex-Mustern

  • \
  • [
  • ]
  • "
  • .
  • *
  • ?

Ebenfalls

Rob kommentierte diese Frage weiter (per E-Mail-Korrespondenz mit mir selbst):

Was die Antwort angeht, ich fürchte, das Chaos ist noch schlimmer, als das Originalplakat vermuten lässt: Die Anforderungen für das Entkommen von Klammern hängen auch davon ab, ob sich die Zeichenfolge in einem Codeblock befindet oder nicht!

Ich schätze, ein automatisiertes Tool könnte einfach vor jedem Zeichen ein Caret einfügen und dann alle Prozentzeichen verdoppeln - und es würde immer noch scheitern, wenn die Zeichenfolge in doppelte Anführungszeichen gesetzt wird!

Ferner sind einzelne Programme für das Parsen ihrer Befehlszeilenargumente verantwortlich, so dass ein Teil des für z. Für sed oder ssed kann dies an den spezifischen Programmen liegen, die in den Stapelskripten aufgerufen werden.

49
Kenny Evitt

Das Escape-Zeichen für batch ist das Caret (^). Wenn Sie eines der Pipeline-Zeichen in Ihr Skript aufnehmen möchten, müssen Sie das Zeichen mit einem Caret voranstellen:

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

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

Sie können einfach eine externe Datei als Eingabe für sed verwenden. 

Wenn Sie Strings direkt im Stapel verwenden, empfiehlt es sich, die verzögerte Erweiterung zu verwenden.

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

EDIT: Verwendung von unmodifizierten Strings mit einem Stapel

Hierbei wird mit findstr die Zeichenfolge direkt aus dem Stapel abgerufen und in eine Ergebnisvariable zurückgegeben.
Sie können also den sed-String verwenden, wie er ist.

@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

Eine einfache Lösung zur Beibehaltung aller Befehlszeilenargumente besteht in der Verwendung von %*: Sie gibt die gesamte Befehlszeile zurück, beginnend mit dem ersten Befehlszeilenargument (in Windows NT 4 schließt %* auch alle führenden Leerzeichen ein) und schließt die Ausgabeumleitung aus.

0
Pino