Как избежать амперсандов в пакетных файлах?

146

Как экранировать амперсанды в командном файле (или из командной строки Windows), чтобы использовать startкоманду для открытия веб-страниц с амперсандами в URL-адресе?

Двойные кавычки не будут работать с start; вместо этого запускается новое окно командной строки.

Обновление 1 : решение Wael Dalloul работает. Кроме того, если в URL есть символы, закодированные в URL (например, пробел закодирован как% 20), и он находится в пакетном файле, то «%» должен быть закодирован как «%%». Это не тот случай в примере.

Пример из командной строки ( CMD.EXE):

start http://www.google.com/search?client=opera&rls=en&q=escape+ampersand&sourceid=opera&ie=utf-8&oe=utf-8

приведет к

http://www.google.com/search?client=opera 

открывается в браузере по умолчанию и эти ошибки в окне командной строки:

'rls' is not recognized as an internal or external command,
operable program or batch file.
'q' is not recognized as an internal or external command,
operable program or batch file.
'sourceid' is not recognized as an internal or external command,
operable program or batch file.
'ie' is not recognized as an internal or external command,
operable program or batch file.
'oe' is not recognized as an internal or external command,
operable program or batch file.

Платформа: Windows XP 64 бит SP2.

Питер Мортенсен
источник
1
Я отредактировал ответ белугабоба, так что теперь он должен работать. Это просто причуды, из-за startкоторых цитирование аргумента терпит неудачу, если применяется без размышлений. В целом, я думаю, что заключить аргумент в кавычки проще и менее подвержено ошибкам, чем избегать каждого символа, который нуждается в экранировании.
Джои
Как насчет знака плюс, +что я должен поставить перед ним, чтобы избежать этого?
Уильям
В PowerShell start "http://www.google.com/search?client=opera&rls=en&q=escape+ampersand&sourceid=opera&ie=utf-8&oe=utf-8"работает, потому что PowerShell
удаляет

Ответы:

91

Из cmd :

  • &экранируется , как это: ^&(основано на @Wael Dalloul в ответ )
  • % не нужно убегать

Пример:

start http://www.google.com/search?client=opera^&rls=en^&q=escape+ampersand%20and%20percentage+in+cmd^&sourceid=opera^&ie=utf-8^&oe=utf-8

Из командного файла

  • &экранируется , как это: ^&(основано на @Wael Dalloul в ответ )
  • %экранируется следующим образом: %%(на основе обновления OP)

Пример:

start http://www.google.com/search?client=opera^&rls=en^&q=escape+ampersand%%20and%%20percentage+in+batch+file^&sourceid=opera^&ie=utf-8^&oe=utf-8
Лассе Кристиансен
источник
Это может также включать пример экранирования "%" - тогда я могу очистить свой вопрос.
Питер Мортенсен
@PeterMortensen Определенно - я обновил свой ответ.
Лассе Кристиансен
2
От каких персонажей я тоже должен сбежать? Я заметил, что я должен бежать "|" на "^ |".
жидкость
В этом случае %не нужно избегать, потому что кто был бы достаточно глуп, чтобы определить 20andв качестве переменной среды? Если вы сделали, start http://www.google.com/search?q=ampersand%20and%20percentageмогли бы http://www.google.com/search?q=ampersandsomething-silly20percentageвместо ссылки . Используя ^%escape в cmd, пример работает как положено.
TamaMcGlinn
145

&используется для разделения команд. Поэтому вы можете использовать, ^чтобы избежать &.

Wael Dalloul
источник
3
Как насчет знака плюс, +что я должен поставить перед ним, чтобы избежать этого?
Уильям
Это более общее применимое решение. Это также работает, если параметр программы командной строки содержит один или несколько амперсандов. Я только что столкнулся с этим - параметр был CGW5COMM & 10C4 & 8301 .
Питер Мортенсен
Цитирование амперсанда с символом каретки ^, похоже, не работает при любых обстоятельствах. Например, попытка выполнить msdeploy.exe с ключом / p: для передачи пароля с амперсандом, похоже, не работает с любой перестановкой, которую я пробовал (кавычка, двойные кавычки, фиктивный первый аргумент).
Дерек Грир
3
Пример использования ^будет неоценимым.
jpmc26
2
@ jpmc26 Я добавил пример в этом ответе .
Лассе Кристиансен
29

Вы можете заключить его в кавычки, если указали фиктивный первый аргумент.

Обратите внимание, что в этом случае вам необходимо указать фиктивный первый аргумент, так как startпервый аргумент будет рассматриваться как заголовок для новых окон консоли, если он указан в кавычках. Таким образом, следующее должно работать (и работает здесь):

start "" "http://www.google.com/search?client=opera&rls=en&q=escape+ampersand&sourceid=opera&ie=utf-8&oe=utf-8"
belugabob
источник
Хорошо, я признаю, что название не полностью соответствует вопросу внутри. (Как вы думаете, я должен сделать название длиннее?)
Питер Мортенсен
В конце концов, не так, «Дох», - заключать в кавычки было правильной идеей - просто не знал о заголовке окна консоли. Спасибо, Йоханнес!
Белогабоб
PowerShell удалит кавычки из аргументов , поэтому это не удастся. Вы должны использовать только start "http://www.google.com/search?client=opera&rls=en&q=escape+ampersand&sourceid=opera&ie=utf-8&oe=utf-8"на PowerShell
phuclv
20
explorer "http://www.google.com/search?client=opera&rls=...."
adatapost
источник
12

Команда

echo this ^& that

работает как положено, выводит

this & that

Команда

echo this ^& that > tmp

также работает, записывая строку в файл "tmp". Тем не менее, перед трубой

echo this ^& that | clip

^ интерпретируется совершенно по-другому. Он пытается записать вывод двух команд «повторить это» и «это» в канал. Сработает эхо, тогда «то» выдаст ошибку. поговорка

echo this ^& echo that | clip

поместит строки «это» и «это» в буфер обмена.

Без ^:

echo this & echo that | clip

первый эхо-сигнал будет записан на консоль, и только выходные данные второго эхо-сигнала будут переданы для ограничения (аналогично для перенаправления «> tmp»). Таким образом, когда вывод перенаправляется, ^ не заключает в кавычки &, а вместо этого вызывает его применение до перенаправления, а не после.

Чтобы передать &, вы должны указать это дважды

echo this ^^^& that | clip

Если вы поместите строку в переменную

set m=this ^& that

затем

set m

будет выводить

m=this & that

но очевидное

echo %m%

не удается, потому что после того, как Windows заменяет переменную, в результате

echo this & that

он анализирует это как новую команду и пытается выполнить «это».

В пакетном файле вы можете использовать отложенное расширение :

setlocal enableDelayedExpansion
echo !m!

Для вывода в канал мы должны заменить все & s в значении переменной на ^ &, что мы можем сделать с помощью синтаксиса% VAR: FROM = TO%:

echo !m:^&=^^^&! | clip

В командной строке «cmd / v» включает отложенное расширение:

cmd /v /c echo !m!

Это работает даже при записи в канал

cmd /v /c echo !m! | clip

Просто.

Денис Хоу
источник
Ваше решение для труб работает, но ваши выводы более или менее неверны. Btw. простая echo this ^^^& that | clipработа тоже. Чтобы понять магическую обработку каналов, вы можете прочитать SO: Почему отложенное расширение завершается неудачно, когда находится внутри переданного блока кода?
Джеб
1

Если вам нужна echoстрока, содержащая амперсанд, кавычки не помогут, потому что вы также увидите их на выходе. В таком случае используйте for:

for %a in ("First & Last") do echo %~a

... в пакетном скрипте:

for %%a in ("First & Last") do echo %%~a

или

for %%a in ("%~1") do echo %%~a
Ярослав Заруба
источник
0

Если у вас есть пробелы в имени файла, и у вас есть символ, вам нужно экранировать:

Вы можете использовать одинарные И двойные кавычки, чтобы избежать ошибок в команде.

scp ./'files name with spaces/internal folder with spaces/"text & files stored.txt"' .

В ^противном случае персонаж избегает кавычек.

быть нс
источник