带有 FIND.exe 的 DOS 批处理 FOR 循环正在去除空行? [英] DOS batch FOR loop with FIND.exe is stripping out blank lines?

查看:24
本文介绍了带有 FIND.exe 的 DOS 批处理 FOR 循环正在去除空行?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

This DOS batch script is stripping out the blank lines and not showing the blank lines in the file even though I am using the TYPE.exe command to convert the file to make sure the file is ASCII so that the FIND command is compatible with the file. Can anyone tell me how to make this script include blank lines?

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

推荐答案

这是 FOR/F 的设计行为 - 它从不返回空行.解决方法是使用 FIND 或 FINDSTR 将行号作为行前缀.如果您可以保证没有行以行号分隔符开头,那么您只需设置适当的分隔符并保留标记 1*,但仅使用第二个标记.

That is the designed behavior of FOR /F - it never returns blank lines. The work around is to use FIND or FINDSTR to prefix the line with the line number. If you can guarantee no lines start with the line number delimiter, then you simply set the appropriate delimiter and keep tokens 1* but use only the 2nd token.

::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 就不会截断.通过管道或重定向从 stdin 读取时,FINDSTR 确实会丢弃长行.

I prefer FINDSTR - it is more reliable. For example, FIND can truncate long lines - FINDSTR does not as long as it reads directly from a file. FINDSTR does drop long lines when reading from stdin via pipe or redirection.

如果文件可能包含以定界符开头的行,则需要保留整行带有行号前缀的行,然后使用搜索和替换删除行前缀.在将 %%A 传输到环境变量时,您可能希望延迟扩展关闭,否则任何 !会被破坏.但是稍后在循环中您需要延迟扩展来进行搜索和替换.

If the file may contain lines that start with the delimiter, then you need to preserve the entire line with the line number prefix, and then use search and replace to remove the line prefix. You probably want delayed expansion off when transferring the %%A to an environment variable, otherwise any ! will be corrupted. But later within the loop you need delayed expansion to do the search and replace.

::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 打开指定为参数或通过重定向的文件会更有效.

If you don't need to worry about converting the file to ASCII, then it is more efficient to drop the pipe and let FIND or FINDSTR open the file specified as an argument, or via redirection.

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

There is another work around that completely bypasses FOR /F during the read process. It looks odd, but it is more efficient. There are no restrictions with using delayed expansion, but unfortunately it has other limitations.

1) 行必须以 <CR><LF> 结束(如果你做 TYPE 文件转换,这不会有问题)

1) lines must be terminated by <CR><LF> (this will not be a problem if you do the TYPE file conversion)

2) 行必须 <= 1021 字节长(不考虑 )

2) lines must be <= 1021 bytes long (disregarding the <CR><LF>)

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

3) any trailing control characters are stripped from each line.

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

4) it must read from a file - you can't use a pipe. So in your case you will need to use a temp file to do your to ASCII conversion.

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"

这篇关于带有 FIND.exe 的 DOS 批处理 FOR 循环正在去除空行?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆