正如 dbenham 所说,它也可以用 for/f 完成,但它有点复杂。
简单的 80% 解决方案是
setlocal EnableDelayedExpansion
set "var="
set LF=^
rem *** Two empty lines are required for the linefeed
FOR /F "delims=" %%a in (myFile.txt) do (
set "var=!var!!LF!%%a"
)
echo !var!
但它失败了:
- 如果一行是空白的,它将被跳过
- 如果一行以;
EOL 字符开头
- 如果一行包含!
(和插入符号)
但是你可以使用更复杂的解决方案
@echo off
SETLOCAL DisableDelayedExpansion
set "all="
FOR /F "usebackq delims=" %%a in (`"findstr /n ^^ aux1.txt"`) do (
set "line=%%a"
SETLOCAL EnableDelayedExpansion
set "line=!line:#=#S!"
set "line=!line:*:=!"
for /F "delims=" %%p in ("!all!#L!line!") do (
ENDLOCAL
set "all=%%p"
)
)
SETLOCAL EnableDelayedExpansion
if defined all (
set "all=!all:~2!"
set ^"all=!all:#L=^
!"
set "all=!all:#S=#!"
)
echo !all!
代码做什么?
首先,findstr /n ^^
将在每一行前面加上一个行号和一个冒号,比如
1:My first Line
2:; beginning with a semicolon
3:
4:there was an empty line
这解决了空行的问题,并且标准的 EOL 字符;
可以被忽略。
要获取该行的内容,将值设置为一个变量,同时禁用延迟扩展,这解决了!
和^
字符的问题。
去掉行号和冒号,会启用延迟扩展(不,delim:
解决不了)。
然后全部#
替换为#S
,这将首先完成,因为删除该行的前缀可能为空并且替换将失败。
但是我为什么要换?
那是因为我不能在这里插入换行符,因为下面的 FOR/F 会因嵌入换行符而失败,
所以我只添加换行符标记(在这种情况下我使用#L
),但文件的内容也可以包含 a #L
,但是通过#
用#S
所有标记 替换所有是唯一的。
在标记之后,使用 关闭/禁用延迟扩展存在问题endlocal
,但保留修改后的all
和line
变量的内容。
这是通过FOR/F-endlocal
技巧完成的,因为可以在屏障 %%p
后面传输内容。endlocal
然后在阅读完整文件后,我检查是否all
已定义,因为对于空文件,它将为空。
然后第一个换行标记 #L
将被删除,所有其他标记都将替换为真正的换行字符。
然后将锐利的安全#S
器恢复为#
.
就是这样,所以即使这个解决方案显然......