使用FIND.exe的DOS批处理FOR循环是否正在删除空白行?

dja*_*fan 9 cmd dos batch-file

即使我使用TYPE.exe命令转换文件以确保文件是ASCII以便FIND命令与文件兼容,这个DOS批处理脚本也会删除空白行而不显示文件中的空行. .谁能告诉我如何让这个脚本包含空白行?

@ECHO off
FOR /F "USEBACKQ tokens=*" %%A IN (`TYPE.exe "build.properties" ^| FIND.exe /V ""`) DO (
  ECHO --%%A--
)
pause
Run Code Online (Sandbox Code Playgroud)

dbe*_*ham 18

这是FOR/F的设计行为 - 它永远不会返回空行.解决方法是使用FIND或FINDSTR在行前面加上行号.如果您可以保证没有行以行号分隔符开头,那么您只需设置适当的分隔符并保持令牌1*但仅使用第二个令牌.

::preserve blank lines using FIND, assume no line starts with ]
::long lines are truncated
for /f "tokens=1* delims=]" %%A in ('type "file.txt" ^| find /n /v ""') do echo %%B

::preserve blank lines using FINDSTR, assume no line starts with :
::long lines > 8191 bytes are lost
for /f "tokens=1* delims=:" %%A in ('type "file.txt" ^| findstr /n "^"') do echo %%B

::FINDSTR variant that preserves long lines
type "file.txt" > "file.txt.tmp"
for /f "tokens=1* delims=:" %%A in ('findstr /n "^" "file.txt.tmp"') do echo %%B
del "file.txt.tmp"
Run Code Online (Sandbox Code Playgroud)

我更喜欢FINDSTR - 它更可靠.例如,FIND可以截断长行 - 只要直接从文件读取,FINDSTR就不会.当通过管道或重定向从stdin读取时,FINDSTR会丢弃长行.

如果文件可能包含以分隔符开头的行,则需要使用行号前缀保留整行,然后使用search and replace删除行前缀.在将%% A传输到环境变量时,您可能希望延迟扩展,否则任何!将被腐蚀.但是后来在循环中你需要延迟扩展来进行搜索和替换.

::preserve blank lines using FIND, even if a line may start with ]
::long lines are truncated
for /f "delims=" %%A in ('type "file.txt" ^| find /n /v ""') do (
  set "ln=%%A"
  setlocal enableDelayedExpansion
  set "ln=!ln:*]=!"
  echo(!ln!
  endlocal
)

::preserve blank lines using FINDSTR, even if a line may start with :
::long lines >8191 bytes are truncated
for /f "delims=*" %%A in ('type "file.txt" ^| findstr /n "^"') do (
  set "ln=%%A"
  setlocal enableDelayedExpansion
  set "ln=!ln:*:=!"
  echo(!ln!
  endlocal
)

::FINDSTR variant that preserves long lines
type "file.txt" >"file.txt.tmp"
for /f "delims=*" %%A in ('findstr /n "^" "file.txt.tmp"') do (
  set "ln=%%A"
  setlocal enableDelayedExpansion
  set "ln=!ln:*:=!"
  echo(!ln!
  endlocal
)
del "file.txt.tmp"
Run Code Online (Sandbox Code Playgroud)

如果您不需要担心将文件转换为ASCII,那么删除管道并让FIND或FINDSTR打开指定为参数的文件或通过重定向更有效.

还有另一种解决方法是在读取过程中完全绕过FOR/F. 它看起来很奇怪,但效率更高.使用延迟扩展没有任何限制,但不幸的是它有其他限制.

1)行必须由<CR> <LF>终止(如果你进行TYPE文件转换,这不会有问题)

2)行必须<= 1021字节长(忽略<CR> <LF>)

3)从每一行中删除任何尾随控制字符.

4)它必须从文件中读取 - 您不能使用管道.因此,在您的情况下,您将需要使用临时文件进行ASCII转换.

setlocal enableDelayedExpansion
type "file.txt">"file.txt.tmp"
for /f %%N in ('find /c /v "" ^<"file.txt.tmp"') do set cnt=%%N
<"file.txt.tmp" (
  for /l %%N in (1 1 %cnt%) do(
    set "ln="
    set /p "ln="
    echo(!ln!
  )
)
del "file.txt.tmp"
Run Code Online (Sandbox Code Playgroud)