Escape-Winkel in einer Windows-Eingabeaufforderung

93

Ich muss eine Zeichenfolge mit spitzen Klammern (<und>) in eine Datei auf einem Windows-Computer übertragen. Grundsätzlich möchte ich Folgendes tun:
echo some string < with angle > brackets >>myfile.txt

Dies funktioniert nicht, da der Befehlsinterpreter mit den spitzen Klammern verwechselt wird. Ich könnte die ganze Zeichenfolge so zitieren:
echo "some string < with angle > brackets" >>myfile.txt

Aber dann habe ich doppelte Anführungszeichen in meiner Datei, die ich nicht möchte.

Das Entkommen der Klammern unter Unix funktioniert auch nicht:
echo some string \< with angle \> brackets >>myfile.txt

Ideen?

Jason
quelle
6
Die Anführungszeichen werden ebenfalls wiederholt.
Dale

Antworten:

171

Das Windows-Escapezeichen ist aus irgendeinem Grund ^.

echo some string ^< with angle ^> brackets >>myfile.txt
Tim Robinson
quelle
10
Nun, Backslash wird für Pfadnamen verwendet und doppelte Anführungszeichen dienen zum Umschließen von Dateinamen mit Leerzeichen, sodass nicht mehr viele Zeichen zur Auswahl stehen.
James Curran
Dies funktioniert auch für andere Zeichen wie kaufmännisches Und (&), danke.
vierundvierzig
2
Funktioniert super! echo some string ^< with angle ^> brackets >>conErgebnisse in: einige Zeichenfolge <mit Winkel> Klammern
Ross Bradbury
1
Alles nur, weil die ursprünglichen PC-Dos Backslash für Pfade und Abwärtskompatibilität verwendeten.
Jahmic
Ich vermute, es war nicht so zufällig. Ich vermute, dass sie ein Zeichen verwenden wollten, das im normalen Text wahrscheinlich nicht vorkommt, damit es nicht leicht vermeidbare, aber unerwünschte Zeichenfluchten verursacht.
David A. Gray
23

Der offizielle Fluchtcharakter ist zwar ^, aber seien Sie vorsichtig, denn manchmal benötigen Sie drei ^ Charaktere. Das ist nur manchmal :

C:\WINDOWS> echo ^<html^>
<html>

C:\WINDOWS> echo ^<html^> | sort
The syntax of the command is incorrect.

C:\WINDOWS> echo ^^^<html^^^> | sort
<html>

C:\WINDOWS> echo ^^^<html^^^>
^<html^>

Ein Trick aus diesem Unsinn besteht darin, einen anderen Befehl als echodie Ausgabe und das Anführungszeichen mit doppelten Anführungszeichen zu verwenden:

C:\WINDOWS> set/p _="<html>" <nul
<html>
C:\WINDOWS> set/p _="<html>" <nul | sort
<html>

Beachten Sie, dass dadurch keine führenden Leerzeichen im Eingabeaufforderungstext erhalten bleiben.

sin3.14
quelle
1
Im zweiten Teil meiner Antwort finden Sie eine Erklärung, warum Rohre mehrere Fluchtwege erfordern.
Dbenham
Die drei ^^^werden auch benötigt, um Befehle in der Azure DOS / Kudu-Konsole zu umgehen.
Lionello
8

Es gibt Methoden, die ^Escape-Sequenzen vermeiden .

Sie können Variablen mit verzögerter Erweiterung verwenden. Unten finden Sie eine Demonstration eines kleinen Batch-Skripts

@echo off
setlocal enableDelayedExpansion
set "line=<html>"
echo !line!

Oder Sie könnten eine FOR / F-Schleife verwenden. Über die Befehlszeile:

for /f "delims=" %A in ("<html>") do @echo %~A

Oder aus einem Batch-Skript:

@echo off
for /f "delims=" %%A in ("<html>") do echo %%~A

Der Grund , warum diese Methoden arbeiten, weil beide verzögerten Expansion und für variable Expansion tritt nach speziellen Operatoren wie <, >, &, |, &&, ||analysiert werden. Siehe Wie analysiert der Windows Command Interpreter (CMD.EXE) Skripts? Für mehr Information.


sin3.14 weist darauf hin, dass Rohre möglicherweise mehrere Fluchtwege erfordern . Beispielsweise:

echo ^^^<html^^^>|findstr .

Der Grund, warum Pipes mehrere Escape-Vorgänge erfordern, liegt darin, dass jede Seite des Pipes in einem neuen CMD-Prozess ausgeführt wird, sodass die Zeile mehrmals analysiert wird. Siehe Warum schlägt die verzögerte Erweiterung fehl, wenn sie sich in einem Pipeline-Codeblock befindet? für eine Erklärung vieler unangenehmer Konsequenzen der Rohrimplementierung von Window.

Es gibt eine andere Methode, um mehrfache Fluchtwege bei der Verwendung von Rohren zu vermeiden. Sie können Ihren eigenen CMD-Prozess explizit instanziieren und das einzelne Escape mit Anführungszeichen schützen:

cmd /c "echo ^<html^>"|findstr .

Wenn Sie die Technik der verzögerten Erweiterung verwenden möchten, um Fluchtwege zu vermeiden, gibt es noch mehr Überraschungen (Sie werden vielleicht nicht überrascht sein, wenn Sie ein Experte für das Design von CMD.EXE sind, aber es gibt keine offizielle MicroSoft-Dokumentation, die dieses Zeug erklärt).

Denken Sie daran, dass jede Seite der Pipe in einem eigenen CMD.EXE-Prozess ausgeführt wird, der Prozess jedoch den verzögerten Expansionsstatus nicht erbt - standardmäßig ist AUS. Sie müssen daher Ihren eigenen CMD.EXE-Prozess explizit instanziieren und die Option / V: ON verwenden, um die verzögerte Erweiterung zu aktivieren.

@echo off
setlocal disableDelayedExpansion
set "line=<html>"
cmd /v:on /c echo !test!|findstr .

Beachten Sie, dass die verzögerte Erweiterung im übergeordneten Batch-Skript deaktiviert ist.

Aber die Hölle bricht los, wenn die verzögerte Erweiterung im übergeordneten Skript aktiviert ist. Folgendes funktioniert nicht :

@echo off
setlocal enableDelayedExpansion
set "line=<html>"
REM - the following command fails
cmd /v:on /c echo !test!|findstr .

Das Problem ist, dass !test!es im übergeordneten Skript erweitert wird, sodass der neue CMD-Prozess versucht, ungeschützt <und zu analysieren >.

Sie könnten dem entkommen !, aber das kann schwierig werden, weil es davon abhängt, ob das !zitiert wird oder nicht.

Wenn nicht angegeben, ist eine doppelte Flucht erforderlich:

@echo off
setlocal enableDelayedExpansion
set "line=<html>"
cmd /v:on /c echo ^^!test^^!|findstr .

Wenn zitiert, wird eine einzelne Flucht verwendet:

@echo off
setlocal enableDelayedExpansion
set "line=<html>"
cmd /v:on /c "echo ^!test^!"|findstr .

Es gibt jedoch einen überraschenden Trick, der alle Escapezeichen vermeidet: Das Einschließen der linken Seite der Pipe verhindert, dass das übergeordnete Skript !test!vorzeitig erweitert wird :

@echo off
setlocal enableDelayedExpansion
set "line=<html>"
(cmd /v:on /c echo !test!)|findstr .

Aber ich nehme an, auch das ist kein kostenloses Mittagessen, da der Batch-Parser am Ende einen zusätzlichen (möglicherweise unerwünschten) Speicherplatz einfügt, wenn Klammern verwendet werden.

Kein Batch-Scripting-Spaß ;-)

Dbenham
quelle
3

Um Sonderzeichen wie '>' unter Windows mit Echo zu verwenden, müssen Sie ein spezielles Escape-Zeichen davor platzieren.

Zum Beispiel

echo A->B

wird nicht funktionieren, da '>' durch '^' maskiert werden muss:

 echo A-^>B

Siehe auch Escape-Sequenzen . Geben Sie hier die Bildbeschreibung ein

Es gibt eine kurze Batch-Datei, die einen grundlegenden Satz von Sonderzeichen und deren Escape-Sequenzen druckt.

Orbitcowboy
quelle
0

Das Entkommen der Klammern unter Unix funktioniert auch nicht:

Echo einige Zeichenfolge \ <mit spitzen \> Klammern >> myfile.txt

Der Backslash würde als Beginn eines absoluten Pfadnamens betrachtet.

James Curran
quelle
2
Absoluter Pfadname relativ zum aktuellen Laufwerksbuchstaben ...;)
dalle
Ein Backslash wird nicht als Beginn eines absoluten Pfadnamens im Text für einen Echo-Befehl betrachtet. Es handelt sich lediglich um einfachen Text, der überall dort weitergeleitet wird, wo Sie ihn senden. - echo \ funktioniert zum Beispiel wie erwartet. - Aber ja, das "\" wäre eine schlechte Wahl für ein Befehlszeilen-Escapezeichen, da jeder Befehl / jedes Programm, das einen Pfad oder Dateinamen benötigt, stattdessen "\" eingeben müsste.
BrainSlugs83
1
Diese Antwort bietet keine Lösung für die zugegebenermaßen vage Frage
G-.
-2

Sie können auch doppelte Anführungszeichen verwenden, um Sonderzeichen zu umgehen ...

echo some string "<" with angle ">" brackets >>myfile.txt
aalaap
quelle
4
Das funktioniert nicht. echo some string "<" with angle ">" brackets >>conführt zu: einigen Zeichenfolgen "<" mit Winkel ">" Klammern, aber das OP möchte einige Zeichenfolgen <mit Winkel> Klammern
Ross Bradbury