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

[原创] 对“批处理for语句从入门到精通”的找茬行动

我记得第一次看到这篇“批处理for语句从入门到精通”的时候,有一种“拨云雾而见天日”的感觉,以前也不是没有学过for,但是总不得要领。

在这里真诚感谢namejm大大花心力写了这么篇好贴。

随着不断在bathome学习、讨论、回答问题,能力也是与日俱增,再回首看这篇“批处理for语句从入门到精通”,除了感叹于namejm在写作上功力不俗外,也发现了不少错漏之处(这点是在所难免的,for命令是批处理的灵魂所在、内容之丰富到了“令人发指”的程度,想要以一人之力写一篇深入浅出、面面俱到的入门教程无疑是一件近似于不可能完成的任务)。

近日学了一句话“只要眼球足够多,虫子再多也不怕”,这是开源界的一句俏皮话,通俗一点来说就是“只要找茬的人多了,错误也就少了”,这话用在这篇教程中也是适用的,所以鉴于这点,写了以上这些文字。

本想发在版主区的,但是写着写着便想到,与其借助bz的力量,不如借助众批友的力量,群众的力量是强大的,人民的力量是毁灭性的。

批处理for语句从入门到精通:http://bbs.bathome.net/thread-2189-1-1.html


找茬回帖规范:
1.账号
2.错误之处/遗漏之处
3.改正/补漏
4.详述“改正/补漏”的理由。

例如:
1.hello123world
2.错误之处:3楼,以上代码不能列出含有隐藏或系统属性的文件;
3.改正:以上代码不能列出含有隐藏属性的文件
4.理由:
  1. @echo off
  2. attrib +s 1.txt
  3. For  %%i in (*.txt) do Echo %%i
  4. pause
复制代码
这里的1.txt在结果中显示出来了。

在找茬过程中修正错误   成长  探索 寻找乐趣

TOP

本帖最后由 qzwqzw 于 2012-3-3 09:31 编辑

不久前在查询关于usebackq的bug信息
结果就搜索了这篇帖子
记起某个茬通过评分提交原作者至今尚无反馈
索性就准备写在这里
请其它版主代为修正

当回过头来再细看那篇经典教程时
不免又发现了一些瑕疵
说是错误也未必尽然
只是确有推敲之处
既成经典就当尽求完美
鼓励怀疑提倡讨论
不可因作者的身份就谨言慎行
否则就迷失了我们讨论的本来目的

不知道为什么版主要求的规范里还要求写帐号
帖子旁边的作者不算吗?
不过还是怎么要求怎么来吧
以下按行文顺序列出我所找到的BUG

1.qzwqzw
2.错误之处:3楼,for %I in (command1) do command2
3.改正:FOR %variable IN (set) DO command [command-parameters],其它段落中相关联的词句和术语建议同时修改
4.理由:
CMD的帮助有时还是靠得住的
况且命令文档的书写自然形成了一定的体例
像楼主的写法
说范式不像范式,因为有%%I
说例句又不像例句,因为有command1/command2
而且无法理解作者为何要将for的set换成command1
1

评分人数

天的白色影子

TOP

1.qzwqzw
2.错误之处:4楼,所有的对象,无论是文件、窗体、还是控件,在所有的非机器语言看来,无外乎都是形如"c:\test.txt"、"CWnd"之类的文本信息...
3.改正:建议整段删除
4.理由:很多对象并非是单纯的文本信息,甚至大部分对象都不是纯文本信息,而是二进制数据,所以作者举的例子并不是很好
天的白色影子

TOP

1.qzwqzw
2.错误之处:4楼,这段代码,主要是让你树立这样一种观念:读取文本文件的内容,请使用 for /f 语句!
3.改正:将“读取文本文件的内容”改为“逐行分析文本文件的内容”
4.理由:读取文本文件内容的方法命令有很多,比如重定向输入,又比如type/more/find/sort等命令
1

评分人数

天的白色影子

TOP

1.qzwqzw
2.错误之处:4楼,在这里,我们引入了一个新的开关:"delims=,"
3.改正:将“开关”改为“选项”,其它相关联内容建议同时修改
4.理由:同3楼帖,windows习惯上将命令之后以/或者-起始的命令行参数叫做开关(switch),而对于for /f 之后的控制信息,系统文档使用的是“选项/选项组”("options")
天的白色影子

TOP

这也算是本人所发现的第一个BUG

1.qzwqzw
2.错误之处:4楼,使用 for /f "eol=" 语句,也就是说,强制指定字符为空,就像对付delims=一样。
3.改正:建议整段删除
4.理由:以前有过讨论,"eol="会指定双引号为行注释字符,所以目前我的取消行注释字符的近似方法,使用eol指定另外一个文本中很难出现的字符作为行注释字符,比如ANSI字符集中控制区字符或者Unicode字符集中的偏僻字符
  1. for /f "eol=" %f in ("""not echo") do @echo %f
复制代码
1

评分人数

天的白色影子

TOP

四楼,[code16] 下方第七行处
原来,for /f 语句是默认忽略以分号打头的行内容的,正如它默认以空格键或跳格键作为字符串的切分字符一样。(hello123world注:eol=;这种默认设置,在delims=;时变得无效。)

建议改成:
原来,for /f 语句是默认忽略第一节以分号打头的行(即使未在 tokens 中对第一节进行声明),正如它默认以空格键或跳格键作为字符串的切分字符一样。
1

评分人数

TOP

hello123world注:eol=;这种默认设置,在delims=;时变得无效。

这里有解释:
for /f 机制的进一步发现
http://www.bathome.net/viewthread.php?tid=5603

TOP

for教程集中整理帖不要忘了这些:
http://www.bathome.net/viewthrea ... amp;page=1#pid30833
http://www.bathome.net/thread-6357-1-1.html
特别注意其中zqz版主的补充。
1

评分人数

TOP

Re qzwqzw 3 楼:
记起某个茬通过评分提交原作者至今尚无反馈

  最近一年多的时间里,因为工作繁忙,另外还在准备考试,基本上很少登录论坛。某日登录论坛的时候,确实发现过qzwqzw兄在帖子中的评价消息发到站内信箱。似乎正碰上论坛程序升级,可能batcher出于节约论坛空间的考虑,以前的站内短信正文全被清空,仅能看到短信通知的纪录;而兄在帖子里的评价留言比较长,仅能显示一部分内容,关键的部分超过显示长度限制而无法阅读。当时没有太多精力来关注这个帖子,因此也就不了了之了。非常抱歉。

当回过头来再细看那篇经典教程时
不免又发现了一些瑕疵
说是错误也未必尽然
只是确有推敲之处
既成经典就当尽求完美
鼓励怀疑提倡讨论
不可因作者的身份就谨言慎行
否则就迷失了我们讨论的本来目的

  说实话,本人不仅不是科班出身,并且所从事的行业和IT领域隔了十万八千里,所以,在IT理论方面其实只是三脚猫的水平,所有的教程,只是在反复的摸索中所积累的一些心得,属于经验之谈,错误的地方肯定会很多,说那篇教程是“经典”,实在是太抬举我了,愧不敢当。从qzwqzw兄历年的帖子可以看出,qzwqzw兄功力深厚,只可惜平时很少露面,留下的帖子非常少,万望兄能多发一些帖子,把我那篇多少有点误人子弟的帖子中的错误一一指出,不甚感激。

To All:
  我之所以挂着荣誉头衔,只是因为曾经管理过论坛,并非表明我的批处理水平就一定比各位高,我所发的教程,无论是否被高亮被置顶,都不代表里面没有一点错误,各位无需把它们视为至理名言而不敢置疑,各位应当“大胆怀疑小心求证”,对有疑问的地方大胆地提出来,以求共同进步。

  最近一段时间诸事繁忙,暂时只收集各位提出的错误之处,等到稍微有空的时候再整体更正,不一定能一一回复,还请各位见谅。同时,在那篇帖子的顶楼链接本帖地址,以提醒后来的阅读者注意本帖中提出的问题。
1

评分人数

    • cjiabing: 原来作者在此。说句公道话,不足是有,但贡 ...PB + 12
尺有所短寸有所长,学好批处理没商量;
考虑问题复杂化,解决问题简洁化。

心在天山,身老沧州。

TOP

回复 11# namejm


难道是传说中的专业挖坑8级证书考试?
我帮忙写的代码不需要付钱。如果一定要给,请在微信群或QQ群发给大家吧。
【微信公众号、微信群、QQ群】http://bbs.bathome.net/thread-3473-1-1.html
【支持批处理之家,加入VIP会员!】http://bbs.bathome.net/thread-67716-1-1.html

TOP

不是证书考试,挂掉了,鸟语还得从头抓起啊,唉,不提也罢,还是回归正题吧,免得一个好好的技术帖又成水帖了。
尺有所短寸有所长,学好批处理没商量;
考虑问题复杂化,解决问题简洁化。

心在天山,身老沧州。

TOP

我也想发一个for教程

TOP

本帖最后由 qzwqzw 于 2012-3-7 17:10 编辑

1.qzwqzw
2.错误之处:5楼,首先,把一条完整的语句读入内存中(不管这条语句有多少行,它们都会被一起读入),然后,识别出哪些部分是命令关键字,哪些是开关、哪些是参数,哪些是变量引用……如果代码语法有误,则给出错误提示或退出批处理环境;如果顺利通过,接下来,就把该条语句中所有被引用的变量及变量两边的百分号对,用这条语句被读入内存之就已经赋予该变量的具体值来替换
3.改正:将“然后,识别出....顺利通过"删除
4.理由:
  1. set "cs=&"
  2. set/p=test1<nul%cs%echo test2
  3. set sw=/l
  4. for %sw% %%i in (1,1,3) do echo %%i--
  5. set cmd=errorcmd
  6. %cmd%
  7. set errsw=/k
  8. dir %errsw%
复制代码
这个问题前几天就发现了
但是为了寻求理论上的确认花费了一些时间
经过数次跟踪分析
发现CMD的词法分析机制异常复杂
为此找了一些NT4下的cmd资料
NT4的CMD不支持变量延迟扩展和很多扩展特性
分析起来相对简单
但仍然没有得到确切的结论

大致可以得出的结论是
CMD首先分析了语句符号(包括() 和 @)
以及命令连接符号(顺序大致是& || && |)
再次分析for / if / rem / 其它命令 / 下级语句
在这些分析的过程中
如果遇到变量符号%则随时进行分析扩展

所以说cmd变量扩展和词法切分是混合进行的
很多特殊符号() | & 等会导致词法切分的退字符动作
%等符号会将缓冲区的字符指针重新定位
也就是说它们都会将命令缓冲区的Token串进行重整
以便在下一步的词法分析中可以继续对扩展结果进行切分和解析
天的白色影子

TOP

返回列表