Объясните, как работает пакетный взлом новой строки в Windows
Может кто-нибудь объяснить, как это работает?
@echo off
REM Creating a Newline variable (the two blank lines are required!)
set NLM=^
set NL=^^^%NLM%%NLM%^%NLM%%NLM%
REM Example Usage:
echo There should be a newline%NL%inserted here.
выделяет:
There should be a newline
inserted here.
2 ответа
Трюк использует поведение кареты.
Также объясняется, что длинные команды разбиты на несколько строк в пакетном файле (.bat) Windows Vista.
Символ каретки является escape-символом для следующего символа или в конце строки используется в качестве многострочного символа, но это почти то же самое.
В конце строки просто экранируется следующий символ, в этом случае <Linefeed>
, но есть скрытая особенность, поэтому, если экранированный символ <LF>
он игнорируется, и следующий символ читается и экранируется, но этот символ всегда будет экранирован, даже если он также <LF>
,
Теперь вы можете понять
set NLM=^
rem Two empty lines are required here
Переменная NLM содержит ровно одну <LF>
персонаж. Но если вы попытаетесь использовать его с echo Line1%NLM%Line2
это терпит неудачу, поскольку синтаксический анализатор прекращает парсинг в единственном <LF>
,
Но это работает
echo Line1^
Line2
Таким образом, вам нужно добавить экранированный перевод строки в строку, и это NL-переменная. Переменная NL состоит только из трех символов.NL=^<LF><LF>
И если это расширяется, он создает только один сбежавший <LF>
как первый <LF>
после каретки будут игнорироваться.
Btw. На мой взгляд, гораздо проще использовать перевод строки с отложенным расширением, так как не нужно ничего избегать.
В этом примере я использую %=EMPTY=%
вместо пустой строки (для самостоятельного комментирования), но как переменная =EMPTY=
не может существовать, он будет расширен до пустой строки.
setlocal EnableDelayedExpansion
(set NLM=^
%=EMPTY=%
)
echo Line1!NLM!Line2
РЕДАКТИРОВАТЬ: добавить некоторые советы для полезного использования <LF>
1) Используйте его как перевод строки в echo
setlocal EnableDelayedExpansion
(set LF=^
%=EMPTY=%
)
echo Line1!LF!Line2
2) Используйте его для разделения команд в скобках
setlocal EnableDelayedExpansion
(set LF=^
%=EMPTY=%
)
(
echo Line1%LF%set x=4%LF%echo !x!%LF%
)
3) Создайте (почти) пустой EOL-символ в цикле FOR /F, как <LF>
это разделитель строк EOL <LF>
такой же, как пустой.
FOR /F ^"eol^=^
delims^=^" %%a in (myFile.php) do echo %%a
4) Используйте LF для разделения текста в цикле FOR /F
setlocal EnableDelayedExpansion
(set LF=^
%=EMPTY=%
)
set "var=Content1;Content2"
FOR /F "delims=" %%a in ("%var:;=!LF!%") do (
echo %%a
)
Кажется, есть способ, который также работает с pipe:
(echo 1st line^
&echo 2nd line) | sort