Escape de los corchetes angulares en un símbolo del sistema de Windows

93

Necesito hacer eco de una cadena que contiene corchetes angulares (<y>) en un archivo en una máquina con Windows. Básicamente, lo que quiero hacer es lo siguiente:
echo some string < with angle > brackets >>myfile.txt

Esto no funciona porque el intérprete de comandos se confunde con los corchetes angulares. Podría citar toda la cadena así:
echo "some string < with angle > brackets" >>myfile.txt

Pero luego tengo comillas dobles en mi archivo que no quiero.

Escapar de los corchetes ala unix tampoco funciona:
echo some string \< with angle \> brackets >>myfile.txt

Ideas?

Jason
fuente
6
Las citas también se repetirán.
dalle

Respuestas:

171

El carácter de escape de Windows es ^, por alguna razón.

echo some string ^< with angle ^> brackets >>myfile.txt
Tim Robinson
fuente
10
Bueno, la barra invertida se usa para los nombres de ruta y las comillas dobles son para ajustar el nombre de archivo que tiene espacios, por lo que no quedan muchas opciones de caracteres.
James Curran
Esto también funciona para otros personajes como ampersand (&), gracias.
diez
2
¡Funciona genial! echo some string ^< with angle ^> brackets >>conresultados en: algunos corchetes <con ángulo> de cadena
Ross Bradbury
1
Todo porque los pc-dos originales usaban barra invertida para rutas y compatibilidad con versiones anteriores.
Jahmic
Sospecho que no fue tan aleatorio. Supongo que querían usar un personaje que era poco probable que apareciera en el texto normal, para que no causara fugas de personajes fácilmente evitables, pero no deseadas.
David A. Gray
23

Es cierto que el personaje de escape oficial es ^, pero ten cuidado porque a veces necesitas tres ^ personajes. Esto es solo a veces :

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 truco de esta tontería es usar un comando que no sea echohacer la salida y citar con comillas dobles:

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

Tenga en cuenta que esto no conservará los espacios iniciales en el texto del mensaje.

pecado3.14
fuente
1
Consulte la segunda parte de mi respuesta para obtener una explicación de por qué las tuberías requieren múltiples escapes.
dbenham
Los tres ^^^también son necesarios para escapar de los comandos en la consola de Azure DOS / Kudu.
lionello
8

Hay métodos que evitan las ^secuencias de escape.

Puede utilizar variables con expansión retardada. A continuación se muestra una pequeña demostración de secuencia de comandos por lotes

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

O puede usar un bucle FOR / F. Desde la línea de comando:

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

O desde un script por lotes:

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

La razón de que estos métodos de trabajo se debe a que tanto la expansión retardada y para la expansión de la variable se producen después de operadores especiales como <, >, &, |, &&, ||se analizan. Consulte ¿Cómo analiza el intérprete de comandos de Windows (CMD.EXE) las secuencias de comandos? para más información.


sin3.14 señala que las tuberías pueden requerir múltiples escapes . Por ejemplo:

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

La razón por la que las tuberías requieren múltiples escapes es porque cada lado de la tubería se ejecuta en un nuevo proceso de CMD, por lo que la línea se analiza varias veces. Consulte ¿Por qué falla la expansión retrasada cuando está dentro de un bloque de código canalizado? para obtener una explicación de muchas consecuencias incómodas de la implementación de la tubería de Windows.

Existe otro método para evitar múltiples fugas al utilizar tuberías. Puede crear una instancia explícita de su propio proceso de CMD y proteger el escape único con comillas:

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

Si desea utilizar la técnica de expansión retardada para evitar fugas, entonces hay aún más sorpresas (es posible que no se sorprenda si es un experto en el diseño de CMD.EXE, pero no hay documentación oficial de MicroSoft que explique estas cosas)

Recuerde que cada lado de la tubería se ejecuta en su propio proceso CMD.EXE, pero el proceso no hereda el estado de expansión retardada, por defecto está APAGADO. Por lo tanto, debe crear una instancia explícita de su propio proceso CMD.EXE y usar la opción / V: ON para habilitar la expansión retardada.

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

Tenga en cuenta que la expansión retrasada está DESACTIVADA en el script de lote principal.

Pero todo el infierno se desata si se habilita la expansión retardada en el script principal. Lo siguiente no funciona:

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

El problema es que !test!está expandido en el script principal, por lo que el nuevo proceso CMD está tratando de analizar archivos desprotegidos <y >.

Podría escapar del !, pero eso puede ser complicado, porque depende de si !se cotiza o no.

Si no se cita, se requiere doble escape:

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

Si se cita, se usa un solo escape:

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

Pero hay un truco sorprendente que evita todos los escapes: encerrar el lado izquierdo de la tubería evita que el script principal se expanda !test!prematuramente:

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

Pero supongo que incluso eso no es un almuerzo gratis, porque el analizador de lotes introduce un espacio adicional (quizás no deseado) al final cuando se usan paréntesis.

No es divertido escribir secuencias de comandos por lotes ;-)

dbenham
fuente
3

Para utilizar caracteres especiales, como '>' en Windows con eco, debe colocar un carácter de escape especial antes.

Por ejemplo

echo A->B

no funcionará ya que '>' tiene que ser escapado por '^':

 echo A-^>B

Consulte también secuencias de escape . ingrese la descripción de la imagen aquí

Hay un archivo por lotes corto, que imprime un conjunto básico de caracteres especiales y sus secuencias de escape.

orbita vaquero
fuente
0

Escapar de los corchetes ala unix tampoco funciona:

echo alguna cadena \ <con ángulo \> corchetes >> miarchivo.txt

La barra invertida se consideraría el inicio de un nombre de ruta absoluto.

James Curran
fuente
2
Nombre de ruta absoluto relativo a la letra de unidad actual ...;)
dalle
Una barra invertida no se considera el comienzo de un nombre de ruta absoluto dentro del texto para un comando de eco; es solo texto sin formato que se envía donde lo envíe. - echo \ por ejemplo, funciona como se esperaba. - Pero sí, el "\" sería una mala elección para un carácter de escape de la línea de comandos, ya que cada comando / programa que necesitara una ruta o nombre de archivo tendría que escribir `\` en su lugar.
BrainSlugs83
1
esta respuesta no ofrece una solución a la pregunta, ciertamente vaga,
G-.
-2

También puede utilizar comillas dobles para escapar de los caracteres especiales ...

echo some string "<" with angle ">" brackets >>myfile.txt
aalaap
fuente
4
Eso no funciona. echo some string "<" with angle ">" brackets >>conda como resultado: algunos corchetes de cadena "<" con ángulo ">" pero el OP quiere algunos corchetes de cadena <con ángulo>
Ross Bradbury