it-swarm.com.de

Escape-spitze Klammern in einer Windows-Eingabeaufforderung

Ich muss eine Zeichenfolge mit spitzen Klammern (<und>) an eine Datei auf einem Windows-Computer senden. 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.

Es funktioniert auch nicht, wenn Sie die eckigen Klammern hinter Unix lassen:
echo some string \< with angle \> brackets >>myfile.txt

Ideen?

88
Jason

Das Windows-Escapezeichen ist aus irgendeinem Grund ^.

echo some string ^< with angle ^> brackets >>myfile.txt
164
Tim Robinson

Richtig, das offizielle Fluchtzeichen ist ^, aber sei vorsichtig, denn manchmal brauchst du drei^ Zeichen. Dies 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 echo zu verwenden, um die Ausgabe und das Anführungszeichen in Anführungszeichen zu setzen:

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

Beachten Sie, dass dadurch keine führenden Leerzeichen im Aufforderungstext beibehalten werden.

23
sin3.14

Es gibt Methoden, die ^-Escape-Sequenzen vermeiden.

Sie können Variablen mit verzögerter Erweiterung verwenden. Unten finden Sie eine kleine Batch-Skript-Demonstration

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

Oder Sie könnten eine FOR/F-Schleife verwenden. Von der Kommandozeile:

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 funktionieren, ist, dass sowohl die verzögerte Erweiterung als auch die FOR-Variablenerweiterung auftreten, nachdem spezielle Operatoren wie <, >, &, |, &&, || analysiert wurden. Weitere Informationen finden Sie unter Wie analysiert der Windows-Befehlsinterpreter (CMD.EXE) Skripte? .


sin3.14 weist darauf hin, dass Pipes möglicherweise mehrere Escapes erfordern . Beispielsweise:

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

Der Grund, warum Pipes mehrere Escapes erfordern, liegt darin, dass jede Seite der 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 Pipe-Codeblock befindet? für eine Erklärung vieler unangenehmer Folgen der Implementierung der Pipe in Windows.

Es gibt eine andere Methode, um bei der Verwendung von Rohren mehrfache Escapezeichen 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 Ausbrüche zu vermeiden, gibt es noch mehr Überraschungen.

Denken Sie daran, dass jede Seite der Pipe in einem eigenen CMD.EXE-Prozess ausgeführt wird, aber der Prozess übernimmt nicht Der verzögerte Erweiterungsstatus ist standardmäßig auf AUS gesetzt. Daher müssen Sie 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 Stapelskript 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! im übergeordneten Skript erweitert ist, sodass der neue CMD-Prozess versucht, ungeschützte < und > zu analysieren.

Sie könnten dem ! entkommen, aber das kann schwierig werden, da es davon abhängt, ob der ! in Anführungszeichen steht oder nicht.

Wenn nicht angegeben, ist ein doppeltes Escape erforderlich:

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

Wenn angegeben, wird ein einzelnes Escape verwendet:

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

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

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

Aber ich nehme auch an, dass dies kein kostenloses Mittagessen ist, da der Batch-Parser am Ende ein zusätzliches (möglicherweise unerwünschtes) Leerzeichen einfügt, wenn Klammern verwendet werden.

Aint Batch-Scripting-Spaß ;-)

7
dbenham

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

Zum Beispiel

echo A->B

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

 echo A-^>B

Siehe auch Escape-Sequenzen . enter image description here

Es gibt eine kurze Batch-Datei, in der ein grundlegender Satz von Sonderzeichen und ihre Escape-Sequenzen gedruckt werden.

2
orbitcowboy

Es funktioniert auch nicht, wenn Sie die eckigen Klammern hinter Unix lassen:

geben Sie einen String\<mit spitzen Klammern \> >> myfile.txt aus

Der umgekehrte Schrägstrich wird als Beginn eines absoluten Pfadnamens betrachtet.

0
James Curran