【问题标题】:IF does not work in BATCH/CMD FOR loops with FOR variable (ie %p)IF 在带有 FOR 变量(即 %p)的 BATCH/CMD FOR 循环中不起作用
【发布时间】:2014-02-14 06:43:40
【问题描述】:

以下命令在 Windows Vista 和更早版本上无法正确运行。它在 Windows 7 及更高版本上运行良好。

BATCH 示例(命名为 whateveryouwanttocallit.cmdsomescript.bat(在这种情况下扩展名无关紧要)):

for /f "tokens=*" %%p in ('ping -n 1 127.0.0.1') do if not "%%p"=="" echo %%p

上面的脚本试图只显示非空行。

在 Windows 7 机器上,生成以下(正确)输出:

Pinging 127.0.0.1 with 32 bytes of data: 
Reply from 127.0.0.1: bytes=32 time<1ms TTL=128 
Ping statistics for 127.0.0.1: 
Packets: Sent = 1, Received = 1, Lost = 0 (0% loss), 
Approximate round trip times in milli-seconds: 
Minimum = 0ms, Maximum = 0ms, Average = 0ms 

在 Windows Vista 和更早版本上,相同的脚本会产生不正确的输出:

ECHO is on.
Pinging 127.0.0.1 with 32 bytes of data:

ECHO is on.
Reply from 127.0.0.1: bytes=32 time<1ms  TTL=128

ECHO is on.
Ping statistics for 127.0.0.1:

Packets: Sent = 1, Received = 1, Lost = 0 (0% loss),

Approximate round trip times in milli-seconds:

Minimum = 0ms, Maximum =  0ms, Average =  0ms

看起来早期的系统有额外的换行符。 早期系统是否有不同的输出格式?有没有办法以适用于早期和后期系统的方式完成此任务?解决方案越简单越好。

【问题讨论】:

  • 在批处理文件中访问令牌时需要双 %...-> 使用 %%p
  • 您还应该使用"delims=" 来解析整行。
  • @npocmaka 我的错误,我应该澄清一下。该问题在 cmd 和批处理脚本中都存在
  • @foxidrive 或者 "tokens=*"。对手头的问题都没有影响
  • FWIW "tokens=*" 去除前导空格,因此解析文件名不可靠。最好始终使用分隔符。

标签: batch-file if-statement for-loop


【解决方案1】:

在 XP 上测试

输出端的所有行,不是像往常那样用0x0D 0x0A(CR-LF),而是用0x0D 0x0D 0x0A

每行末尾都有一个额外的回车符。这不会干扰您在数据行中的代码,但会在“空”行中产生错误。

for 命令处理输入时,如果没有任何变量/可替换参数获取数据,则忽略该行并且不执行do 部分中的代码。但是在这种情况下,没有明显内容的行有内容,一个0x0D字符被读取并分配给%p。所以该行不会被忽略,do 部分被执行,if 在条件下返回 false,因为变量包含内容,echo 命令尝试输出回车。但照原样,echo 命令解释该行没有内容,echo on/off 输出到控制台。

要避免 echo on/off 输出到控制台,请使用 echo(%p

为避免处理“空”行,过滤 ping 命令输出

for /f "tokens=*" %p in ('ping -n 1 127.0.0.1 ^| findstr /r "[a-z]"') do ....

【讨论】:

  • 非常好的解决方案!这正是我所需要的
  • 我知道,现在我知道为什么了。 +1 非常好的解释
  • 只要 (%p) 行不与任何其他文本组合,此功能就有效。但它包含尾随的 0x0D,如果您需要附加其他字符,这可能会导致问题。有关删除尾随 0x0D 的简单解决方案,请参阅 my answer
【解决方案2】:

FOR /F 将从每一行(如果存在)中删除一个尾随 0x0D 字符。所以另一种选择是添加一个额外的 FOR /F 循环:

for /f "delims=" %%A in ('ping -n 1 127.0.0.1') do for /f "delims=" %%B in ("%%A") do echo %%B

【讨论】:

    猜你喜欢
    • 2021-06-13
    • 2016-02-09
    • 1970-01-01
    • 2018-03-28
    • 2012-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多