Escape dos colchetes angulares em um prompt de comando do Windows

93

Preciso repetir uma string contendo colchetes angulares (<e>) para um arquivo em uma máquina Windows. Basicamente, o que eu quero fazer é o seguinte:
echo some string < with angle > brackets >>myfile.txt

Isso não funciona, pois o interpretador de comandos se confunde com os colchetes angulares. Eu poderia citar toda a string assim:
echo "some string < with angle > brackets" >>myfile.txt

Mas tenho aspas duplas em meu arquivo que não quero.

Escapar os colchetes ala unix também não funciona:
echo some string \< with angle \> brackets >>myfile.txt

Ideias?

Jason
fonte
6
As citações também serão ecoadas.
dalle

Respostas:

171

O caractere de escape do Windows é ^, por algum motivo.

echo some string ^< with angle ^> brackets >>myfile.txt
Tim Robinson
fonte
10
Bem, a barra invertida é usada para nomes de caminho e aspas duplas são usadas para envolver o nome do arquivo que contém espaços, então não há muitas opções de caracteres restantes.
James Curran,
Isso também funciona para outros caracteres como o e comercial (&), obrigado.
dez
2
Funciona bem! echo some string ^< with angle ^> brackets >>conresulta em: alguns colchetes <com ângulos> de string
Ross Bradbury
1
Tudo porque os pc-dos originais usavam barra invertida para caminhos e compatibilidade com versões anteriores.
Jahmic
Eu suspeito que não foi tão aleatório. Meu palpite é que eles queriam usar um caractere que provavelmente não aparecesse no texto normal, de modo que não causasse escapes de caractere facilmente evitáveis, mas indesejados.
David A. Gray
23

É verdade que o caractere de escape oficial é ^, mas tome cuidado porque às vezes você precisa de três ^ caracteres. Às vezes é assim :

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

Um truque desse absurdo é usar um comando diferente de echofazer a saída e aspas com aspas duplas:

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

Observe que isso não preservará os espaços à esquerda no texto do prompt.

sen3.14
fonte
1
Veja a 2ª parte da minha resposta para uma explicação de por que os tubos requerem vários escapes.
dbenham
Os três ^^^também são necessários para escapar dos comandos no console DOS / Kudu do Azure.
lionello
8

Existem métodos que evitam ^sequências de escape.

Você pode usar variáveis ​​com expansão atrasada. Abaixo está uma pequena demonstração de script em lote

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

Ou você pode usar um loop FOR / F. Na linha de comando:

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

Ou de um script em lote:

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

A razão destes métodos de trabalho é porque tanto a expansão atrasada e para a expansão variável ocorrer após operadores especiais, como <, >, &, |, &&, ||são analisados. Consulte Como o Windows Command Interpreter (CMD.EXE) analisa scripts? para mais informações.


sin3.14 aponta que os tubos podem exigir vários escapes . Por exemplo:

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

O motivo pelo qual os tubos requerem vários escapes é porque cada lado do tubo é executado em um novo processo CMD, de modo que a linha é analisada várias vezes. Consulte Por que a expansão atrasada falha quando dentro de um bloco de código canalizado? para obter uma explicação das muitas consequências estranhas da implementação do pipe do Windows.

Existe outro método para evitar vários escapes ao usar tubos. Você pode instanciar explicitamente seu próprio processo CMD e proteger o escape único com aspas:

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

Se você quiser usar a técnica de expansão retardada para evitar escapes, então há ainda mais surpresas (você pode não se surpreender se for um especialista no design do CMD.EXE, mas não há documentação oficial da MicroSoft que explique essas coisas)

Lembre-se de que cada lado do tubo é executado em seu próprio processo CMD.EXE, mas o processo não herda o estado de expansão atrasado - o padrão é OFF. Portanto, você deve instanciar explicitamente seu próprio processo CMD.EXE e usar a opção / V: ON para ativar a expansão atrasada.

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

Observe que a expansão atrasada está DESLIGADA no script de lote pai.

Mas tudo se perde se a expansão atrasada for habilitada no script pai. O seguinte não funciona:

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

O problema é que !test!está expandido no script pai, de modo que o novo processo CMD está tentando analisar <e desprotegido >.

Você pode escapar do !, mas isso pode ser complicado, porque depende se o !está citado ou não.

Se não estiver entre aspas, é necessário um escape duplo:

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

Se estiver entre aspas, um único escape é usado:

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

Mas há um truque surpreendente que evita todas as fugas - fechar o lado esquerdo do tubo evita que o script pai se expanda !test!prematuramente:

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

Mas suponho que mesmo isso não seja um almoço grátis, porque o analisador de lote introduz um espaço extra (talvez indesejado) no final quando os parênteses são usados.

Aint batch scripting divertido ;-)

dbenham
fonte
3

Para usar caracteres especiais, como '>' no Windows com echo, você precisa colocar um caractere de escape especial antes dele.

Por exemplo

echo A->B

não funcionará, pois '>' deve ser escapado por '^':

 echo A-^>B

Veja também sequências de escape . insira a descrição da imagem aqui

Existe um pequeno arquivo em lote, que imprime um conjunto básico de caracteres especiais e suas sequências de escape.

orbitcowboy
fonte
0

Escapar os colchetes ala unix também não funciona:

echo alguma string \ <com ângulo \> colchetes >> meuarquivo.txt

A barra invertida seria considerada o início de um nome de caminho absoluto.

James Curran
fonte
2
Nome do caminho absoluto relativo à letra da unidade atual ...;)
dalle
Uma barra invertida não é considerada o início de um nome de caminho absoluto dentro do texto para um comando echo - é apenas um texto simples que é canalizado para onde quer que você o envie. - echo \ por exemplo, funciona conforme o esperado. - Mas sim, o "\" seria uma má escolha para um caractere de escape da linha de comando, já que cada comando / programa que necessitasse de um caminho ou nome de arquivo você teria que digitar `\` ao invés.
BrainSlugs83
1
esta resposta não oferece uma solução para a questão, reconhecidamente vaga
G-.
-2

Você também pode usar aspas duplas para escapar de caracteres especiais ...

echo some string "<" with angle ">" brackets >>myfile.txt
aalaap
fonte
4
Isso não funciona. echo some string "<" with angle ">" brackets >>conresulta em: alguns colchetes "<" com ângulo ">" de string,
Ross Bradbury