Échapper les crochets angulaires dans une invite de commande Windows

93

J'ai besoin de faire écho à une chaîne contenant des crochets angulaires (<et>) dans un fichier sur une machine Windows. En gros, ce que je veux faire est ce qui suit:
echo some string < with angle > brackets >>myfile.txt

Cela ne fonctionne pas car l'interpréteur de commandes est confondu avec les crochets angulaires. Je pourrais citer toute la chaîne comme ceci:
echo "some string < with angle > brackets" >>myfile.txt

Mais ensuite, j'ai des guillemets doubles dans mon fichier que je ne veux pas.

Échapper les crochets ala unix ne fonctionne pas non plus:
echo some string \< with angle \> brackets >>myfile.txt

Des idées?

Jason
la source
6
Les citations seront également reprises.
dalle

Réponses:

171

Le caractère d'échappement de Windows est ^, pour une raison quelconque.

echo some string ^< with angle ^> brackets >>myfile.txt
Tim Robinson
la source
10
Eh bien, la barre oblique inverse est utilisée pour les noms de chemin et les guillemets doubles sont pour envelopper les noms de fichiers qui ont des espaces, donc il ne reste plus beaucoup de choix de caractères.
James Curran
Cela fonctionne également pour d'autres personnages comme esperluette (&), merci.
tenfour
2
Fonctionne très bien! echo some string ^< with angle ^> brackets >>conrésultats dans: une chaîne <avec angle> crochets
Ross Bradbury
1
Tout cela parce que le pc-dos d'origine utilisait une barre oblique inverse pour les chemins et la compatibilité descendante.
Jahmic
Je soupçonne que ce n'était pas si aléatoire. Je suppose qu'ils voulaient utiliser un caractère qui était peu susceptible d'apparaître dans un texte normal, de sorte que cela n'entraîne pas d'échappements de caractères facilement évitables, mais indésirables.
David A. Gray
23

Certes, le caractère d'échappement officiel l'est ^, mais soyez prudent car parfois vous avez besoin de trois ^ personnages. C'est juste parfois :

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

Une astuce pour sortir de ce non-sens consiste à utiliser une commande autre que echode faire la sortie et de citer entre guillemets:

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

Notez que cela ne conservera pas les espaces de début sur le texte de l'invite.

sin3.14
la source
1
Voir la 2ème partie de ma réponse pour une explication des raisons pour lesquelles les tuyaux nécessitent plusieurs évasions.
dbenham
Les trois ^^^sont également nécessaires pour échapper aux commandes dans la console Azure DOS / Kudu.
lionello
8

Il existe des méthodes qui évitent les ^séquences d'échappement.

Vous pouvez utiliser des variables avec une expansion retardée. Voici une petite démonstration de script batch

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

Ou vous pouvez utiliser une boucle FOR / F. Depuis la ligne de commande:

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

Ou à partir d'un script batch:

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

La raison pour laquelle ces travaux de méthodes est à la fois parce que l' expansion retardée et d'expansion variables se produisent après les opérateurs spéciaux comme <, >, &, |, &&, ||sont analysés. Consultez Comment l'interpréteur de commandes Windows (CMD.EXE) analyse-t-il les scripts? pour plus d'informations.


sin3.14 souligne que les tuyaux peuvent nécessiter plusieurs échappements . Par exemple:

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

La raison pour laquelle les tubes nécessitent plusieurs échappements est que chaque côté du tube est exécuté dans un nouveau processus CMD, de sorte que la ligne est analysée plusieurs fois. Voir Pourquoi l'expansion retardée échoue-t-elle à l'intérieur d'un bloc de code canalisé? pour une explication des nombreuses conséquences gênantes de l'implémentation du pipe de Window.

Il existe une autre méthode pour éviter les échappements multiples lors de l'utilisation de tuyaux. Vous pouvez explicitement instancier votre propre processus CMD et protéger l'échappement simple avec des guillemets:

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

Si vous souhaitez utiliser la technique d'expansion retardée pour éviter les échappées, il y a encore plus de surprises (vous ne serez peut-être pas surpris si vous êtes un expert de la conception de CMD.EXE, mais il n'y a pas de documentation officielle MicroSoft qui explique cela)

N'oubliez pas que chaque côté du tube est exécuté dans son propre processus CMD.EXE, mais que le processus n'hérite pas de l'état d'expansion retardé - il est par défaut sur OFF. Vous devez donc explicitement instancier votre propre processus CMD.EXE et utiliser l'option / V: ON pour activer l'expansion retardée.

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

Notez que l'expansion retardée est désactivée dans le script de lot parent.

Mais tout l'enfer se déchaîne si l'expansion retardée est activée dans le script parent. Ce qui suit ne fonctionne pas :

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

Le problème est qu'il !test!est développé dans le script parent, de sorte que le nouveau processus CMD essaie d'analyser les fichiers non protégés <et >.

Vous pouvez échapper à !, mais cela peut devenir délicat, car cela dépend du fait que le !est cité ou non.

S'il n'est pas indiqué, un double échappement est requis:

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

S'il est cité, un seul échappement est utilisé:

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

Mais il existe une astuce surprenante qui évite toutes les échappements - enfermer le côté gauche du tube empêche le script parent de se développer !test!prématurément:

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

Mais je suppose que même ce n'est pas un déjeuner gratuit, car l'analyseur de lots introduit un espace supplémentaire (peut-être indésirable) à la fin lorsque des parenthèses sont utilisées.

N'est pas amusant de script par lots ;-)

Dbenham
la source
3

Pour utiliser des caractères spéciaux, tels que «>» sous Windows avec écho, vous devez placer un caractère d'échappement spécial devant lui.

Par exemple

echo A->B

ne fonctionnera pas car '>' doit être échappé par '^':

 echo A-^>B

Voir aussi les séquences d'échappement . entrez la description de l'image ici

Il existe un petit fichier batch, qui imprime un jeu de base de caractères spéciaux et leurs séquences d'échappement.

orbitcowboy
la source
0

Échapper les crochets ala unix ne fonctionne pas non plus:

echo une chaîne \ <avec des angles \> crochets >> monfichier.txt

La barre oblique inverse serait considérée comme le début d'un chemin absolu.

James Curran
la source
2
Chemin absolu par rapport à la lettre de lecteur actuelle ...;)
dalle
Une barre oblique inverse n'est pas considérée comme le début d'un nom de chemin absolu dans le texte d'une commande d'écho - c'est juste du texte brut qui est diffusé partout où vous l'envoyez. - echo \ par exemple fonctionne comme prévu. - Mais oui, le "\" serait un mauvais choix pour un caractère d'échappement de ligne de commande car chaque commande / programme nécessitant un chemin ou un nom de fichier devrait taper "\" à la place.
BrainSlugs83
1
cette réponse n'offre pas de solution à la question, certes vague,
G-.
-2

Vous pouvez également utiliser des guillemets doubles pour échapper les caractères spéciaux ...

echo some string "<" with angle ">" brackets >>myfile.txt
aalaap
la source
4
Cela ne fonctionne pas. echo some string "<" with angle ">" brackets >>conrésultats dans: des crochets de chaîne "<" avec angle ">" mais l'OP veut des crochets de chaîne <avec angle>
Ross Bradbury