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

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

7 ответов

Решение

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

Пример:

copy file1.txt file2.txt

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

copy file1.txt^
 file2.txt

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

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

Вы можете использовать каретку несколько раз, но максимальная длина строки не должна превышать 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

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

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

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

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

Примеры: (все протестировано на 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.)

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

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

Несколько команд могут быть помещены в круглые скобки и распределены по многочисленным строкам; так что-то вроде 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 (
...

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

if exist ^

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

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

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

Одна вещь, которую я не нашел при поиске «как разделить длинную строку командного файла DOS», - это как разделить что-то, содержащее длинный цитируемый текст. На самом деле это описано в ответах выше, но не очевидно. Используйте Карет, чтобы избежать их. например

      myprog "needs this to be quoted"

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

      myprog ^"needs this ^
to be quoted^"

но остерегайтесь начинать строку с каретки после завершения строки с кареткой - потому что она будет отображаться как каретка ..?:

      echo ^"^
needs this ^
to be quoted^
^"

-> "нужно, чтобы это было процитировано ^"

Хотя карретка будет предпочтительным способом сделать это, вот еще один подход:

@echo off
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
set "{{=setlocal enableDelayedExpansion&for %%a in (" & set "}}="::end::" ) do if "%%~a" neq "::end::" (set command=!command! %%a) else (call !command! & endlocal)"
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

%{{%
    echo
    "command"
    written
    on a
    few lines
%}}%

Команду легче читать без каретки, но использование специальных символов, например скобок, перенаправления и т. д., нарушит ее. Так что вы можете это сделать для более простых случаев. Хотя вы все равно можете заключать параметры в двойные кавычки

Другие вопросы по тегам