解释Windows批处理换行符变量hack的工作方式


72

有人可以解释一下它是如何工作的吗?

@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.

你怎么能回响在批处理文件换行符?


除了创建新的空白行之外,还有其他理由吗?
Mechaflash 2011年

1
有很多我为回答添加了一些解释
jeb 2011年

Answers:


91

技巧使用插入符号的行为。在Windows Vista批处理(.bat)文件中分成多行的长命令中
也进行了说明

插入符号是下一个字符的转义字符,或者在行尾用作多行字符,但这几乎是相同的。

在行尾,它只是转义下一个字符,在这种情况下是<Linefeed>,但是有一个隐藏的功能,因此,如果转义的字符是a,<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>符将被忽略。

顺便说一句。在我看来,使用换行符和延迟的扩展要容易得多,因为不需要转义任何内容。
在此示例中,我使用%=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)在FOR / F循环中创建一个(几乎)空的EOL字符,因为<LF>EOL的行定界符<LF>与一个空的EOL相同。

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
)

好话题!如何在构建多行字符串后将换行符插入要回显的字符串中?谢谢
RGuggisberg 2016年

@RGuggisberg我不确定我是否收到您的问题,但也许您的意思是set multiStr=Line1!LF!Line2 & echo !multiStr!
jeb

啊,是的!得到它了。感谢jeb
RGuggisberg,2016年

5

似乎有一个办法,也可用于管道:

(echo 1st line^
&echo 2nd line) | sort

但这也会对每一行进行排序。因此,此技巧不适用于连接多行文件
Armin
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.