[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖

[已解决]批处理中defined在for中运用为何失效?

今天遇到一个很奇怪的现象:
  1. @echo off&setlocal enabledelayedexpansion
  2. for /f %%a in (1.txt) do (
  3. set w=%%a
  4. if defined w (echo !w!) else (echo 无字符)
  5. )
  6. pause
复制代码
这段代码应该是如果1.txt里有字符,就显示,没有则显示无字符。但实际效果为,当1.txt无字符时,没有echo 无字符这个显示。还以为是else失效了。然后我又改成
  1. @echo off&setlocal enabledelayedexpansion
  2. for /f %%a in (1.txt) do (
  3. set w=%%a
  4. if not defined w (echo 无字符) else (echo !w!)
  5. )
  6. pause
复制代码
也是没有echo 无字符这个显示。那就不与else有关系。

只有把代码改成下面的就可以,好奇怪!我只是举了一个例子,实际是在其他的代码中发现了这个问题。希望大家帮我分析下,是不是哪里错了。
  1. @echo off&setlocal enabledelayedexpansion
  2. for /f %%a in (1.txt) do (
  3. set w=%%a
  4. )
  5. if defined w (echo !w!) else (echo 无字符)
  6. pause
复制代码
1

评分人数

    • batman: 感谢给帖子标题标注[已解决]字样PB + 2

对于新手确实有点难理解,努力学习.

TOP

14# zm900612


学习学习,原来是再次执行时将::做为%1的值来屏闭自己
世界上没有学不会的知识,也没有想得到却做不到的事!

TOP

本帖最后由 zm900612 于 2011-7-13 16:27 编辑

12# Hello123World

流程如下:
  1. rem 双击 1.bat
  2. @cmd /c "%1" %*
  3. rem 默认情况下以 cmd /c 执行 bat 脚本,由于是双击运行,所以 %* 为空
  4. @echo off
  5. rem 脚本中的第一行,关闭回显
  6. %1 cmd /k %0 ::
  7. rem %1 为空,所以执行了 cmd /k 1.bat ::,开启一个新的 cmd 来执行自身,注意此时 %1 的值变为 :: 了
  8. @echo off
  9. rem 因为是在新的 cmd 中,所以又从头执行一遍,第二次执行脚本的第一行,关闭回显。
  10. %1 cmd /k %0 ::
  11. rem 此时 %1 等于 ::,所以 cmd 把这行理解成注释而跳过,从而在脚本内部完成了从 cmd /c 到 cmd /k 的切换。
复制代码

TOP

5楼同学习。

TOP

%1 cmd /k %0 ::
这一句怎么理解,%0代表bat自身,%1代表什么,还有就是::,这里%1和::都是不能缺少的。

TOP

本帖最后由 zm900612 于 2011-7-12 19:11 编辑

10# q115643492

碰到莫名其妙错误时,我常常用以下几种方法差错:
  1. 错误退出时,改用 cmd /k 启动 bat ,碰到错误退出的情况时不会完全退出 cmd
  2. 怀疑某些部分未执行或者结果异常时,在关键的节点开回显、下断点、输出到文件、单步执行
  3. 代码的任何地方都有可能是错误源、不知道具体哪个部分出错时,可以用折半法或者每隔 N 行标记一个 cmd /q /v:on 和 pause ,逐段检查
  4. 找到了出问题的命令,但是出错原因却匪夷所思时,木油办法了,要么摆渡股沟,要么咨询别人,要么自己瞎蒙吧...
复制代码
比如楼主这个刚运行时就退出了,用 cmd /k 执行发现错在 in(,加上分隔符后仍然出错,于是扔个 echo !w!&pause 到 for 中单步执行,发现是空循环,症结就找到了...
  1. @echo off&setlocal enabledelayedexpansion
  2. %1 cmd /k %0 ::
  3. ::改用 cmd /k 启动自身
  4. for /f %%a in(1.txt) do (
  5.    set w=%%a
  6.    echo !w!&pause
  7.    rem 单步执行
  8.    if defined w (echo !w!) else (echo 无字符)
  9. )
  10. pause>nul
复制代码
不知道大家怎么查错的,有木有人交流下?

TOP

超版主是用来说明If Defined的正确用法罢了,实际上用%%~za是不是为0来判别文本是否为空更准确了
ArdentMan 发表于 2011-7-12 17:18


对,我是在其他用途中遇到的这个问题,拿文本来请教只是简单罢了,主要是If Defined的正确用法,呵呵.

TOP

本帖最后由 zm900612 于 2011-7-12 17:51 编辑

8# ArdentMan


用文件大小来判断,用途比较单一,万一文本有bom呢?比如utf-8

TOP

超版主是用来说明If Defined的正确用法罢了,实际上用%%~za是不是为0来判别文本是否为空更准确了
一路飘过的鸟~~~

TOP

本帖最后由 mxxcgzxxx 于 2011-7-12 18:40 编辑

这样也可以,比FOR更少时间
  1. findstr "." 1.txt||echo 无字符
复制代码
世界上没有学不会的知识,也没有想得到却做不到的事!

TOP

3# batman

哦,明白了,还是基本东西不懂,学习了。
当()为空时,for循环整个都不会执行。以后会注意了。
谢谢了!

TOP

2# else

in后面有空格,书写都对了,先是我打错了,改过来了。
1.txt是存在的,测试了好多次。第3个代码则可以显示

TOP

  1. @echo off&setlocal enabledelayedexpansion
  2. for /f %%a in(1.txt) do (
  3. set w=%%a
  4. if defined w (echo !w!) else (echo 无字符)
  5. )
  6. pause
复制代码
以上代码当1.txt为空时,for循环整个都不会执行,哪来的后面的显示,正确代码如下:
  1. @echo off
  2. for /f %%a in (1.txt) do set "flag=a"
  3. if defined flag (
  4.    echo 有字符
  5.   ) else (
  6.    echo 无字符
  7. )
  8. pause>nul
复制代码
更简单的:
  1. @echo off
  2. set "flag=无"
  3. for /f %%a in (1.txt) do set "flag=有"
  4. echo %flag%字符
  5. Pause>nul
复制代码
2

评分人数

***共同提高***

TOP

返回列表