Разделение длинных команд на несколько строк через пакетный файл Windows

735

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

Ондра Жижка
источник

Ответы:

919

Вы можете разбить длинные строки с помощью каретки, ^если помните, что каретка и символ новой строки после нее полностью удалены. Итак, если должен быть пробел, где вы ломаете линию, включите пробел. ( Подробнее об этом ниже. )

Пример:

copy file1.txt file2.txt

будет написано как:

copy file1.txt^
 file2.txt
Wayne
источник
95
Вы можете начать следующую строку без пробела, если вы добавите пробел непосредственно перед ^и после текста вашей команды.
Джозеф Дейгл
4
@SebaIllingworth - Нет, вы всегда можете добавить [ПРОБЕЛ] + [^] и две пустые строки, чтобы создать всего 2 перевода строки при редактировании echo.
Джеймс К
12
В целях безопасности всегда используйте пустые строки при использовании каретки, см. Простой карат в пакетном файле
занимает
4
@GavinMiller: « символ вставки ^ после копирования и file1.txt в новой строке не будут работать». Это неправда. Вы можете разбить строку в любом месте, в том числе в середине слова, как co^␍py ^␍file1 ^␍file2. Я предлагаю вам удалить свой комментарий, чтобы избежать путаницы, тем более что этот вопрос такой популярный
Бородин
3
Здесь есть одна проблема: ^ должен быть последним символом в строке - то есть без пробелов после. У меня были проблемы с этим, и оказалось, что после каретки у меня есть куча пробелов, которые не так легко увидеть в редакторе, который я использовал.
GregHNZ
267

Правило для кареты:

Каретка в конце строки добавляет следующую строку, первый символ добавленной строки будет экранирован.

Вы можете использовать каретку несколько раз, но максимальная длина строки не должна превышать 8192 символа (Windows XP, Windows Vista и Windows 7).

echo Test1
echo one ^
two ^
three ^
four^
*
--- Output ---
Test1
one two three four*

echo Test2
echo one & echo two
--- Output ---
Test2
one
two

echo Test3
echo one & ^
echo two
--- Output ---
Test3
one
two

echo Test4
echo one ^
& echo two
--- Output ---
Test4
one & echo two

Чтобы подавить выход следующего символа, вы можете использовать перенаправление.

Перенаправление должно быть перед кареткой. Но существует одно любопытство с перенаправлением перед каретой.

Если вы поместите токен в каретку, он будет удален.

echo Test5
echo one <nul ^
& echo two
--- Output ---
Test5
one
two


echo Test6
echo one <nul ThisTokenIsLost^
& echo two
--- Output ---
Test6
one
two

И также возможно встраивать перевод строки в строку:

setlocal EnableDelayedExpansion
set text=This creates ^

a line feed
echo Test7: %text%
echo Test8: !text!
--- Output ---
Test7: This creates
Test8: This creates
a line feed

Пустая строка важна для успеха. Это работает только с отложенным расширением, иначе остальная часть строки игнорируется после перевода строки.

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

Джеб
источник
Последний блок кода с примером перевода строки не отображает пустую строку, даже если она там есть. (По крайней мере, это не отображается в IE7) Попробуйте переформатировать, используя вместо этого цитату.
Дбенхам
5
Вопрос в том, должны ли мы поддерживать плохой инструмент, который не следует правилам (кто-то называет это браузером, но это не так), или вам следует переключиться на браузер?
Джеб
1
у меня были двойные кавычки, окружающие мои значения, как в set var = "text here ^", но это не работает. Удалите двойную кавычку, и это нормально.
RJT
1
@jeb, написал пример неудачного сценария cmd, но затем нашел этот вопрос: stackoverflow.com/questions/4643376/…
rjt
Это не работает, если следующая строка начинается с кавычки: copy ^[newline]"file1.txt" ^[newline]"file2.txt"не работает! Я должен был добавить пробел: copy ^[newline] "file1.txt" ^[newline] "file2.txt".
Александр Гельбух
70

(Это, в основном, переписывание ответа Уэйна, но с путаницей вокруг прояснения каретки. Поэтому я опубликовал его как CW. Я не стесняюсь редактировать ответы, но полностью переписывать их кажется неуместным)

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

Примеры: (все протестировано на Windows XP и Windows 7)

xcopy file1.txt file2.txt

можно записать как:

xcopy^
 file1.txt^
 file2.txt

или

xcopy ^
file1.txt ^
file2.txt

или даже

xc^
opy ^
file1.txt ^
file2.txt

(Это последнее работает, потому что между пробелами xcи ^и нет пробелов, а в начале следующей строки пробелов нет. Поэтому, когда вы удаляете ^и новую строку , вы получаете .... xcopy)

Для удобочитаемости и здравомыслия, вероятно, лучше разбивать только между параметрами (не забудьте указать пробел).

Убедитесь, что ^это не последнее, что есть в командном файле, так как это, похоже, является серьезной проблемой .

Т.Дж. Crowder
источник
18

Несколько команд могут быть помещены в круглые скобки и распределены по многочисленным строкам; так что-то вроде echo hi && echo helloможно поставить так:

( echo hi
  echo hello )

Также переменные могут помочь:

set AFILEPATH="C:\SOME\LONG\PATH\TO\A\FILE"
if exist %AFILEPATH% (
  start "" /b %AFILEPATH% -option C:\PATH\TO\SETTING...
) else (
...

Кроме того, я заметил с помощью carets ( ^), что ifусловным выражениям нравилось, что они следовали только при наличии пробела:

if exist ^
Тодд Партридж
источник
1
Строка cmd1.bat && cmd2.batотличается от формы parens: выполняется, cmd2.batесли cmd1.batвыполняется успешно (-без настройки %errorcode%). Последняя форма выполняется безоговорочно. Несколько неожиданным (по крайней мере для меня) является то, что, очевидно, вы не можете использовать комбинацию обоих +, то есть добавить &&до разрыва строки.
Пол Михалик
( echo <line break here> hello )приводит к пустой строке.
Карл Моррисон
лучший и самый чистый ответ! в регулярных выражениях капризы уродливы и проблематичны
neoscribe
9

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

for %n in (hello
bye) do echo %n

Обратите внимание, что после приветствия или до свидания даже не требуется места.

Мохаммед Сафват
источник
Конечно, это является частью forсинтаксиса: разделителями элементов в «for-set» являются пробел, запятая, точка с запятой, знак равенства, символ табуляции и новые строки.
Аасини
Но что если doчасть содержит несколько вложенных if-elseоператоров?
Вики Дев
Тогда вы можете просто использовать круглые скобки, чтобы заключить операторы, как для% n, в (привет пока), делать (эхо% n, эхо% n)
Мохаммед Сафват,