DOS 批处理 FOR 循环与 FIND.exe 正在删除空白行?
即使我使用 TYPE.exe 命令转换文件以确保文件是 ASCII 以便 FIND 命令与文件兼容,此 DOS 批处理脚本也会删除文件中的空行并且不显示文件中的空行。谁能告诉我如何使这个脚本包含空行?
@ECHO off
FOR /F "USEBACKQ tokens=*" %%A IN (`TYPE.exe "build.properties" ^| FIND.exe /V ""`) DO (
ECHO --%%A--
)
pause
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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
这是 FOR /F 的设计行为 - 它永远不会返回空行。解决方法是使用 FIND 或 FINDSTR 在行前添加行号。如果您可以保证没有行以行号分隔符开头,那么您只需设置适当的分隔符并保留标记 1* 但仅使用第二个标记。
我更喜欢 FINDSTR - 它更可靠。例如,FIND 可以截断长行,而 FINDSTR 则不能,只要它直接从文件中读取即可。通过管道或重定向从 stdin 读取时,FINDSTR 确实会丢弃长行。
如果文件可能包含以分隔符开头的行,则需要保留带有行号前缀的整行,然后使用搜索和替换来删除行前缀。当将 %%A 传输到环境变量时,您可能希望关闭延迟扩展,否则任何!将会被损坏。但稍后在循环中,您需要延迟扩展来进行搜索和替换。
如果您不需要担心将文件转换为 ASCII,那么删除管道并让 FIND 或 FINDSTR 打开指定为参数的文件或通过重定向会更有效。
还有另一种解决方法可以在读取过程中完全绕过 FOR /F。看起来很奇怪,但效率更高。使用延迟扩展没有任何限制,但不幸的是它还有其他限制。
1) 行必须以结束; (如果进行 TYPE 文件转换,这不会成为问题)
2) 行的长度必须 <= 1021 字节(忽略)
3) 从每行中删除任何尾随控制字符。
4)它必须从文件中读取 - 你不能使用管道。因此,在您的情况下,您将需要使用临时文件来进行 ASCII 转换。
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.
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.
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.
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.
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) lines must be terminated by <CR><LF> (this will not be a problem if you do the TYPE file conversion)
2) lines must be <= 1021 bytes long (disregarding the <CR><LF>)
3) any trailing control characters are stripped from each line.
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.
我编写了一个非常简单的程序,当用于此目的时,它可以替代 FIND 和 FINDSTR 命令。我的程序叫
PIPE.COM
,它只是在空行中插入一个空格,所以所有的行都可以直接用FOR
命令处理,不需要进一步的调整(只要因为插入的空格不关心)。这里是:编辑:附录作为新评论的答案
:DefinePipe 子例程中的代码创建一个名为 pipeline.com 的 88 字节程序,它基本上执行与此等效的过程伪批处理代码:
这样,输入文件中的空行会被带有一个空格的行更改,因此 FOR /F 命令不再省略它们。正如我在回答中所说,“只要插入的空间不关心”,这就有效。
请注意,pipe.com 程序无法在 64 位 Windows 版本中运行。
安东尼奥
I wrote a very simple program that may serve as replacement for
FIND
andFINDSTR
commands when they are used for this purpose. My program is calledPIPE.COM
and it just insert a blank space in empty lines, so all the lines may be directly processed byFOR
command with no further adjustments (as long as the inserted space don't cares). Here it is:EDIT: Addendum as answer to new comment
The code at :DefinePipe subroutine create a 88 bytes program called pipe.com, that basically do a process equivalent to this pseudo-Batch code:
This way, empty lines in the input file are changed by lines with one space, so FOR /F command not longer omit they. This works "as long as the inserted space don't cares" as I said in my answer.
Note that the pipe.com program does not work in 64-bits Windows versions.
Antonio
输出行包括空行
这是我为自己使用而开发的方法。
将代码保存为批处理文件,例如 SHOWALL.BAT 并将源文件作为命令行参数传递。
输出可以被重定向或通过管道传输。
示例:
showall source.txt
showall source.txt > destination.txt
showall source.txt | FIND "string"
一个奇怪的地方是包含'^<' (重定向)而不是仅仅执行以下操作:
通过省略重定向,将输出前导空行。
Output lines including blank lines
Here's a method I developed for my own use.
Save the code as a batch file say, SHOWALL.BAT and pass the source file as a command line parameter.
Output can be redirected or piped.
EXAMPLES:
showall source.txt
showall source.txt >destination.txt
showall source.txt | FIND "string"
An oddity is the inclusion of the '^<' (redirection) as opposed to just doing the following:
By omitting the redirection, a leading blank line is output.
感谢 dbenham,这可行,尽管与他的建议略有不同:
Thanks to dbenham, this works, although it is slightly different than his suggestion:
正如上述问题的 this 答案中提到的,默认情况下使用
for 似乎不会跳过行/f
(至少)Windows XP
(社区 - 请通过在您的Windows
版本和服务包上测试以下批处理命令来更新此答案) 。编辑:根据Jeb的下面的评论,似乎
ping
命令,至少在Windows XP
中是导致
for /f
产生
而不是空行(如果有人具体知道原因,会如果他们可以更新此答案或评论,我们将不胜感激)。
作为解决方法,似乎是第二个默认分隔标记(示例中的
/%%b
)返回为
空白
,这适用于我通过“父级”消除空白行的情况if
以for /f
开头的第二个标记为条件,如下所示:使用下面的代码:
.... 以下是我在 Windows XP、Windows 7 和 Windows 2008 上看到的,这是唯一的三个版本我可以随时访问的 Windows 服务包:
As mentioned in this answer to the above question, it doesn't seem that lines are skipped by default using
for /f
in (at least)Windows XP
(Community - Please update this answer by testing the below batch commands on your version & service pack ofWindows
).EDIT: Per Jeb's comment below, it seems that the
ping
command, in at leastWindows XP
, iscausing
for /f
to produce<CR>
's instead of blank lines (If someone knows specifically why, wouldappreciate it if they could update this answer or comment).
As a workaround, it seems that the second default delimited token (
<space>
/%%b
in the example)returns as
blank
, which worked for my situation of eliminating the blank lines by way of an "parent"if
conditional on the second token at the start of thefor /f
, like this:Using the below code:
.... the following is what I see on Windows XP, Windows 7 and Windows 2008, being the only three versions & service packs of Windows I have ready access to: