Wie kann ich einem Ausrufezeichen entkommen! in cmd-Skripten?

75

Wenn ich setlocal ENABLEDELAYEDEXPANSIONein Cmd-Skript festgelegt habe, gibt es eine Möglichkeit, einem zu entkommen! dass ich als Parameter für einen Befehl verwenden möchte?

@echo off
setlocal ENABLEDELAYEDEXPANSION
echo I want to go out with a bang!
echo I still want to go out with a bang^!
Andy Morris
quelle

Antworten:

11

Nachfolgend finden Sie ein Beispiel, wie wir die Ausrufezeichenvariable im Status DISABLEDELAYEDEXPANSION und ENABLEDELAYEDEXPANSION verwenden können .

@echo off
setlocal DISABLEDELAYEDEXPANSION
set DB_password=encrypt!Pws
echo %DB_password%
SETLOCAL ENABLEDELAYEDEXPANSION
echo !DB_password!
Aditya Sharma
quelle
Beste Antwort! Dies löst die Verwendung in Skripten, in denen DELAYEDEXPANSION benötigt wird.
JasonXA
Das ist aberrativ. Nirgendwo in den Anforderungen ist das Gedächtnis ein Problem, und dennoch benutze ich es häufig ohne negative Auswirkungen. Behalten Sie Ihren Unsinn für sich, es sei denn, Sie können tatsächlich etwas beitragen.
JasonXA
Ich habe meinen Code tatsächlich wie Ihren geschrieben und dann gedacht, "das kann nicht funktionieren, weil das! Bei aktivierter verzögerter Erweiterung verloren geht", habe im gesamten Internet nach einer Lösung gesucht, bin hier gelandet, habe die letzte Antwort gelesen und herausgefunden, dass mein Code dies hätte hat die ganze Zeit funktioniert, ich habe nur nicht bemerkt, dass es nur einmal ersetzt wird ... Vielen Dank ^! ^! ; D
timlg07
84

Das habe ich gefunden (^^)

@echo off
setlocal ENABLEDELAYEDEXPANSION
echo I want to go out with a bang^^!
FrVaBe
quelle
2
Übrigens, wenn Sie ein Ausrufezeichen innerhalb einer Variablen ersetzen müssten, wie würden Sie das tun?
Crosenblum
2
@ Crosenblum Ich würde empfehlen, dies als eigene Frage zu stellen. Dann wird es für alle SO-Mitglieder sichtbar sein und höchstwahrscheinlich beantwortet.
FrVaBe
1
Dies (und auch die anderen Lösungen) funktionieren nicht, wenn sich das Ausrufezeichen in einer Variablen befindet, die Sie festlegen / verwenden oder an eine Anrufbezeichnung weitergeben. In diesem Fall haben Sie wahrscheinlich kein Glück.
Abel
64

Eine zusätzliche Bemerkung zur Antwort von FrVaBe .

Normalerweise ^^!funktioniert das, aber in Anführungszeichen brauchen Sie ^!stattdessen nur.

echo I want to go out with a bang^^!
echo He said "Bang^!"

Dies ist ein Ergebnis des Escape-Mechanismus des Batch-Parsers.

Zuerst analysiert der Parser eine Zeile und das Caret entgeht dem nächsten Zeichen. In diesem Fall wirkt es sich auf &|<>()"<linefeed>Anführungszeichen aus , jedoch nur außerhalb von Anführungszeichen, da innerhalb der Anführungszeichen alle Zeichen "normal" sind und das Caret selbst keine Auswirkung hat.

Bei verzögerter Erweiterung folgt ein zusätzlicher Analyseschritt, es gibt dem Caret auch ein Escape-Zeichen für das nächste Zeichen, das jedoch nur das !und beeinflusst ^, und Anführungszeichen werden in diesem Analyseschritt ignoriert. Dieser zusätzliche Schritt wird nur ausgeführt, wenn mindestens einer !in der Zeile vorhanden ist.

setlocal DisableDelayedExpansion
echo DisableDelayedExpansion
echo one caret^^
echo one caret^^  bang! "boom^!"

echo(
setlocal EnableDelayedExpansion
echo EnableDelayedExpansion
echo one caret^^
echo none caret^^  bang^^! "boom^!"

---- AUSGABE ------

DisableDelayedExpansion
one caret^
one caret^  bang! "boom^!"

EnableDelayedExpansion
one caret^
none caret  bang! "boom!"


BEARBEITEN

Hier ist ein leicht modifiziertes Beispiel, das die verschiedenen Escape-Permutationen, die je nach Kontext erforderlich sind, besser veranschaulicht. Der einzige Fall, der ein ungewöhnliches Entweichen erfordert, ist das letzte Beispiel, wenn die verzögerte Erweiterung aktiviert ist und mindestens eines !in der Leitung vorhanden ist.

@echo off
setlocal DisableDelayedExpansion
echo DisableDelayedExpansion
echo caret^^       "caret^"
echo caret^^ bang! "caret^ bang!"

echo(
setlocal EnableDelayedExpansion
echo EnableDelayedExpansion
echo caret^^       "caret^"
echo caret^^^^ bang^^! "caret^^ bang^!"

-- AUSGABE --

DisableDelayedExpansion
caret^       "caret^"
caret^ bang! "caret^ bang!"

EnableDelayedExpansion
caret^       "caret^"
caret^ bang! "caret^ bang!"
jeb
quelle
6

Vielen Dank. Wenn das Skript eine Variable enthält, deren Wert ein "!" Enthält, wird dieser Wert durch den folgenden Ansatz unverändert wiedergegeben:

@echo aus
SETLOCAL EnableDelayedExpansion
set / P omg = Geben Sie einen Wert ein, der ein Ausrufezeichen enthält:
Echo Traditionell:% omg%
echo Alternative :! omg!
Pause
Original-Paulie-D
quelle