Esci dalle parentesi angolari in un prompt dei comandi di Windows


93

Ho bisogno di echo una stringa contenente parentesi angolari (<e>) in un file su una macchina Windows. Fondamentalmente quello che voglio fare è il seguente:
echo some string < with angle > brackets >>myfile.txt

Questo non funziona poiché l'interprete dei comandi viene confuso con le parentesi angolari. Potrei citare l'intera stringa in questo modo:
echo "some string < with angle > brackets" >>myfile.txt

Ma poi ho le virgolette doppie nel mio file che non voglio.

Anche l'escape delle parentesi ala unix non funziona:
echo some string \< with angle \> brackets >>myfile.txt

Idee?


6
Anche le citazioni verranno ripetute.
Dalle

Risposte:


171

Il carattere di escape di Windows è ^, per qualche motivo.

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

10
Bene, la barra rovesciata viene utilizzata per i nomi di percorso e le virgolette doppie servono per avvolgere il nome del file che ha spazi, quindi non sono rimaste molte scelte di caratteri.
James Curran

Questo funziona anche per altri personaggi come la e commerciale (&), grazie.
tenfour

2
Funziona alla grande! echo some string ^< with angle ^> brackets >>conrisultati in: alcune parentesi di stringa <con angolo>
Ross Bradbury

1
Tutto perché i pc-dos originali utilizzavano il backslash per i percorsi e la compatibilità con le versioni precedenti.
Jahmic

Sospetto che non sia stato poi così casuale. La mia ipotesi è che volessero usare un personaggio che era improbabile che apparisse nel testo normale, in modo che non causasse fughe di caratteri facilmente evitabili, ma indesiderate.
David A. Gray,

23

È vero, il carattere di fuga ufficiale è ^, ma fai attenzione perché a volte hai bisogno di tre ^ caratteri. Questo è solo a volte :

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^>

Un trucco per evitare queste sciocchezze è usare un comando diverso echodall'esecuzione dell'output e delle virgolette tra virgolette:

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

Notare che ciò non manterrà gli spazi iniziali sul testo del prompt.


1
Vedi la seconda parte della mia risposta per una spiegazione del perché i tubi richiedono più escape.
dbenham,

I tre ^^^sono necessari anche per sfuggire ai comandi nella console Azure DOS / Kudu.
lionello

8

Esistono metodi che evitano le ^sequenze di escape.

È possibile utilizzare variabili con espansione ritardata. Di seguito è riportata una piccola dimostrazione di script batch

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

Oppure potresti usare un ciclo FOR / F. Dalla riga di comando:

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

O da uno script batch:

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

La ragione per cui questi metodi di lavoro è a causa sia l'espansione ritardata e per l'espansione variabile si verificano dopo gli operatori speciali come <, >, &, |, &&, ||vengono analizzati. Vedi Come vengono analizzati gli script da Command Interpreter (CMD.EXE) di Windows? per maggiori informazioni.


sin3.14 sottolinea che i tubi possono richiedere più escape . Per esempio:

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

Il motivo per cui le pipe richiedono più escape è perché ogni lato della pipe viene eseguito in un nuovo processo CMD, quindi la riga viene analizzata più volte. Vedi Perché l'espansione ritardata non riesce quando all'interno di un blocco di codice reindirizzato? per una spiegazione di molte conseguenze scomode dell'implementazione del pipe di Windows.

Esiste un altro metodo per evitare più escape quando si utilizzano pipe. Puoi creare un'istanza esplicita del tuo processo CMD e proteggere il singolo escape con virgolette:

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

Se vuoi utilizzare la tecnica di espansione ritardata per evitare fughe, allora ci sono ancora più sorprese (potresti non essere sorpreso se sei un esperto del design di CMD.EXE, ma non esiste una documentazione ufficiale MicroSoft che spieghi queste cose)

Ricorda che ogni lato della pipe viene eseguito nel proprio processo CMD.EXE, ma il processo non eredita lo stato di espansione ritardata: il valore predefinito è OFF. Quindi è necessario creare un'istanza esplicita del proprio processo CMD.EXE e utilizzare l'opzione / V: ON per abilitare l'espansione ritardata.

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

Tieni presente che l'espansione ritardata è disattivata nello script batch principale.

Ma si scatena l'inferno se l'espansione ritardata è abilitata nello script principale. Quanto segue non funziona:

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

Il problema è che !test!è espanso nello script principale, quindi il nuovo processo CMD sta tentando di analizzare non protetti <e >.

Potresti sfuggire al !, ma questo può diventare complicato, perché dipende dal fatto che !sia citato o meno.

Se non citato, è richiesta una doppia escape:

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

Se citato, viene utilizzata una singola escape:

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

Ma c'è un trucco sorprendente che evita tutte le fughe: racchiudere il lato sinistro del pipe impedisce allo script genitore di espandersi !test!prematuramente:

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

Ma suppongo che anche questo non sia un pranzo gratuito, perché il parser batch introduce uno spazio extra (forse indesiderato) alla fine quando vengono utilizzate le parentesi.

Non è divertente creare script in batch ;-)


3

Per utilizzare caratteri speciali, come ">" su Windows con eco, è necessario inserire un carattere di escape speciale prima di esso.

Per esempio

echo A->B

non funzionerà poiché '>' deve essere preceduto da '^':

 echo A-^>B

Vedi anche sequenze di escape . inserisci qui la descrizione dell'immagine

C'è un breve file batch, che stampa un set di base di caratteri speciali e le loro sequenze di escape.


0

Anche l'escape delle parentesi ala unix non funziona:

echo alcune stringhe \ <con parentesi angolari \> >> miofile.txt

La barra rovesciata sarebbe considerata l'inizio di un percorso assoluto.


2
Assoluta percorso relativo alla lettera di unità corrente ...;)
Dalle

Una barra rovesciata non è considerata l'inizio di un nome di percorso assoluto all'interno del testo per un comando echo: è solo testo semplice che viene convogliato ovunque lo invii. - echo \ ad esempio funziona come previsto. - Ma sì, la "\" sarebbe una cattiva scelta per un carattere di escape della riga di comando poiché ogni comando / programma che necessitava di un percorso o di un nome file dovresti invece digitare "\".
BrainSlugs83

1
questa risposta non offre una soluzione alla domanda, dichiaratamente vaga,
G-.

-2

Puoi anche usare le virgolette doppie per sfuggire ai caratteri speciali ...

echo some string "<" with angle ">" brackets >>myfile.txt

4
Non funziona. echo some string "<" with angle ">" brackets >>conrisultati in: alcune parentesi di stringa "<" con angolo ">" ma l'OP vuole alcune parentesi di stringa <con angolo>
Ross Bradbury
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.