Экранирование угловых скобок в командной строке Windows


95

Мне нужно вывести строку, содержащую угловые скобки (<и>), в файл на компьютере с Windows. В основном я хочу сделать следующее:
echo some string < with angle > brackets >>myfile.txt

Это не работает, поскольку интерпретатор команд путается с угловыми скобками. Я мог бы процитировать всю строку так:
echo "some string < with angle > brackets" >>myfile.txt

Но тогда в моем файле есть двойные кавычки, которые мне не нужны.

Экранирование скобок ala unix тоже не работает:
echo some string \< with angle \> brackets >>myfile.txt

Идеи?


6
Цитаты также будут повторены.
далле

Ответы:


171

По какой-то причине escape-символ Windows - ^.

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

10
Что ж, обратная косая черта используется для имен путей, а двойные кавычки предназначены для обертывания имени файла с пробелами, поэтому осталось не так много вариантов символов.
Джеймс Карран,

Это также работает для других символов, таких как амперсанд (&), спасибо.
tenfour,

2
Работает отлично! echo some string ^< with angle ^> brackets >>conприводит к: некоторые строковые скобки <с углом>
Росс Брэдбери

1
Все потому, что исходный pc-dos использовал обратную косую черту для обозначения путей и обратной совместимости.
Jahmic

Я подозреваю, что все было не так уж случайно. Я предполагаю, что они хотели использовать символ, который вряд ли может появиться в обычном тексте, чтобы он не приводил к легко устранимым, но нежелательным побегам символов.
Дэвид А. Грей

25

Правда, официальный escape-символ есть ^, но будьте осторожны, потому что иногда вам нужно три ^ символа. Это просто иногда :

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

Один из трюков из этой ерунды - использовать команду, echoотличную от вывода и заключения в двойные кавычки:

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

Обратите внимание, что это не сохранит начальные пробелы в тексте подсказки.


1
Во второй части моего ответа вы узнаете, почему для каналов требуется несколько экранирований.
dbenham

1
Эти три ^^^также необходимы для экранирования команд в консоли Azure DOS / Kudu.
lionello

Я обнаружил, что это действительно необходимо, если вы хотите сохранить значение, содержащее заостренные скобки, в хранилище ключей Azure с помощью Azure CLI.
Яап,

8

Есть методы, позволяющие избежать ^escape-последовательностей.

Вы можете использовать переменные с отложенным расширением. Ниже представлена ​​небольшая демонстрация пакетного сценария.

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

Или вы можете использовать цикл FOR / F. Из командной строки:

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

Или из пакетного скрипта:

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

Причина этих методы работа , потому что оба отсроченное расширение и для расширения переменного происходит после специальных операторов , такие как <, >, &, |, &&, ||обрабатывается. См. Как интерпретатор команд Windows (CMD.EXE) анализирует сценарии? для получения дополнительной информации.


sin3.14 указывает, что для каналов может потребоваться несколько экранирований . Например:

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

Причина, по которой для каналов требуется несколько экранирований, заключается в том, что каждая сторона канала выполняется в новом процессе CMD, поэтому строка анализируется несколько раз. См. Почему не удается отложенное расширение внутри блока кода, передаваемого по конвейеру? для объяснения многих неудобных последствий реализации канала Window.

Есть еще один способ избежать многократных выходов при использовании каналов. Вы можете явно создать экземпляр своего собственного процесса CMD и защитить одиночный escape-код кавычками:

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

Если вы хотите использовать технику отложенного расширения, чтобы избежать побега, тогда есть еще больше сюрпризов (вы можете не удивиться, если вы эксперт по дизайну CMD.EXE, но нет официальной документации MicroSoft, объясняющей этот материал)

Помните, что каждая сторона конвейера выполняется в своем собственном процессе CMD.EXE, но процесс не наследует состояние отложенного раскрытия - по умолчанию оно выключено. Таким образом, вы должны явно создать экземпляр своего собственного процесса CMD.EXE и использовать параметр / V: ON, чтобы включить отложенное расширение.

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

Обратите внимание, что отложенное расширение отключено в родительском пакетном сценарии.

Но ад вырвется наружу, если в родительском скрипте включено отложенное расширение. Следующее не работает:

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

Проблема в том, что !test!это расширено в родительском скрипте, поэтому новый процесс CMD пытается проанализировать незащищенные <и >.

Вы можете избежать !, но это может быть сложно, потому что это зависит от того, !цитируется или нет.

Если не кавычки, то требуется двойной escape:

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

В кавычках используется единственный escape-код:

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

Но есть удивительный трюк, который позволяет избежать всех экранирований - включение левой части канала предотвращает !test!преждевременное расширение родительского скрипта :

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

Но я полагаю, что даже это не бесплатный обед, потому что пакетный синтаксический анализатор вводит дополнительное (возможно, нежелательное) пространство в конце, когда используются круглые скобки.

Не весело писать сценарии ;-)


3

Чтобы использовать специальные символы, такие как '>' в Windows с эхо, вам необходимо поместить перед ним специальный escape-символ.

Например

echo A->B

не будет работать, так как '>' должно быть экранировано '^':

 echo A-^>B

См. Также escape-последовательности . введите описание изображения здесь

Существует небольшой командный файл, который печатает базовый набор специальных символов и их управляющих последовательностей.


0

Экранирование скобок ala unix тоже не работает:

введите строку \ <с углом \> скобки >> myfile.txt

Обратная косая черта будет считаться началом абсолютного пути.


2
Абсолютный путь относительно текущей буквы диска ...;)
dalle

Обратная косая черта не считается началом имени абсолютного пути внутри текста для команды echo - это просто текст, который передается по конвейеру, куда бы вы его ни отправили. - echo \ например работает как положено. - Но да, "\" было бы плохим выбором для escape-символа командной строки, так как для каждой команды / программы, которым нужен путь или имя файла, вам придется вместо этого набирать `\`.
BrainSlugs83

1
этот ответ не предлагает решения на, по общему признанию, расплывчатый вопрос
G-.

-2

Вы также можете использовать двойные кавычки для экранирования специальных символов ...

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

4
Это не работает. echo some string "<" with angle ">" brackets >>conприводит к: некоторые строковые скобки "<" с углом ">", но OP хочет некоторые строковые скобки <с углом>
Росс Брэдбери
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.