batch-file - DOS 批处理 FOR 循环与 FIND.exe 正在删除空白行?

标签 batch-file dos cmd

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

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

最佳答案

这是 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"

我更喜欢 FINDSTR - 它更可靠。例如,FIND 可以截断长行,而 FINDSTR 则不能,只要它直接从文件中读取即可。通过管道或重定向从标准输入读取时,FINDSTR 确实会丢弃长行。

如果文件可能包含以分隔符开头的行,则需要保留带有行号前缀的整行,然后使用搜索和替换来删除行前缀。当将 %%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"

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

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

1) 行必须以 终止(如果您进行 TYPE 文件转换,这不会成为问题)

2) 行的长度必须 <= 1021 字节(忽略 )

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"

关于batch-file - DOS 批处理 FOR 循环与 FIND.exe 正在删除空白行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8811992/

相关文章:

batch-file - 使用 ENABLEDELAYEDEXPANSION

assembly - 以美元结尾的字符串

windows - 使用 Windows 命令行查看文件是否存在并重命名

windows - Windows cmd.exe 中是否有等同于 'cut -c' 的内容?

windows - 批量检查盘符是否存在,否则转到另一段代码

batch-file - 验证变量是否为数字

JDBC批量插入OutOfMemoryError

windows-7 - 登录时在 Windows 7 中自动运行 bat 脚本

shell - 如何在 diff 查看器仍然打开的情况下让cleartool diff 返回到命令行?

date - 使用 DOS 批处理文件备份最近 7 天的文件夹