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 ;-)