中国DOS联盟论坛

中国DOS联盟

-- 联合DOS 推动DOS 发展DOS --

联盟域名:www.cn-dos.net  论坛域名:www.cn-dos.net/forum
DOS,代表着自由开放与发展,我们努力起来,学习FreeDOS和Linux的自由开放与GNU精神,共同创造和发展美好的自由与GNU GPL世界吧!

游客:  注册 | 登录 | 命令行 | 会员 | 搜索 | 上传 | 帮助 »
中国DOS联盟论坛 » DOS疑难解答 & 问题讨论 (解答室) » 运行XMSDSK 后,在他的虚拟盘目录下,循环FOR就不支持*统配符了?
作者:
标题: 运行XMSDSK 后,在他的虚拟盘目录下,循环FOR就不支持*统配符了? 上一主题 | 下一主题
GOTOmsdos
铂金会员

C++启程者


积分 5154
发帖 1827
注册 2003-7-18
状态 离线
『楼 主』:  运行XMSDSK 后,在他的虚拟盘目录下,循环FOR就不支持*统配符了?

刚发现XMSDSK 的BUG??
运行XMSDSK 后,在他的虚拟盘目录下,循环FOR就不支持*统配符了!
换成硬盘目录下,就可以了!

狂晕!!!
有没有谁碰到过??


2005-5-22 00:00
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
willsort
元老会员

Batchinger


积分 4432
发帖 1512
注册 2002-10-18
状态 离线
『第 2 楼』:  

Re GOTOmsdos:  请详细描述一下,比如你的问题代码以及它的执行结果。



※ Batchinger 致 Bat Fans:请访问 [讨论]批处理编程的异类 ,欢迎交流与共享批处理编程心得!
2005-5-23 00:00
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
GOTOmsdos
铂金会员

C++启程者


积分 5154
发帖 1827
注册 2003-7-18
状态 离线
『第 3 楼』:  

比如,XMSDSK 后的盘是Z:
有WBAT目录
在Z:\WBAT目录下: (也有Z:\LEGEND,D:\LEGEND目录和()中文件)
Z:\WBAT>for %a in (s*.grp r*.idx) do copy d:\legend\%a z:\legend /y
但执行后,无任何出错提示! (用%%A批处理也一样)
但奇怪的是:换成了硬盘上的目录为当前目录后,再运行同样的以上命令,就可以了!
后用%1式的命令行参数的批处理才可以(仍在Z:\WBAT目录,因为我的程序一定要在此目录).
但是,更奇怪的是:有时又可以! 环境没有什么不同!

[此贴子已经被作者于2005-5-23 21:55:30编辑过]




2005-5-23 00:00
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
willsort
元老会员

Batchinger


积分 4432
发帖 1512
注册 2002-10-18
状态 离线
『第 4 楼』:  

Re GOTOmsdos:

  可以确定问题出在你对FOR命令遍历集合的理解上,而非XMSDSK虚拟盘的问题。

  for %a in (s*.grp r*.idx) do copy d:\legend\%a z:\legend /y

  IN语句后()中内容被称为FOR的遍历集合,其中可以包含多个集合元素,每个元素之间以空格、分号、等号等参数分隔符分隔。FOR将按以下过程一一处理所有的集合元素。

  如果集合元素中含有文件名通配符(星号或问号),则FOR将此元素理解为文件名,它将在当前路径或者元素中所指定的路径下寻找可以对应的文件。如果找到,则一一替换DO中的FOR变量名并执行它;如果未找到,则不执行DO语句,也不作任何提示。

  如果集合元素中不含有文件名通配符,则FOR首先将其假定为文件名,并在当前路径下或在元素中指定的路径下寻找对应的文件。如果找到,则替换并执行DO后的语句;如果未找到,则将其理解为普通意义的字符串,替换并执行DO后的语句。另外,在集合元素的替换过程中,如果元素中指定了路径,那么其替换后的FOR变量中也将包含同样的路径,反之亦然。

  而在你的实例中,因为 s*.grp r*.idx 包含星号这个通配符,所以被FOR理解为文件名,且其中并未指定路径,则FOR缺省在当前路径下搜索对应的文件。所以,当你在Z:\WBAT中执行FOR,自然会因为未找到文件而不作任何动作,而当在硬盘目录下(应该是d:\legend)执行后,因为可以找到文件,所以执行正常。使用%1也是基于同样的原因。

  所以解决的办法是:

  for %a in (d:\legend\s*.grp;d:\legend\r*.idx) do copy %a z:\legend /y

  另外,copy命令用于批处理文件中,将自动启动/y开关,即自动覆盖已存在文件,除非全局的环境变量copycmd被设置并包含开关/-y。

  需要说明的是,这仅是在MS-DOS或者Win9x命令行下的FOR所具有的特性,在WinNT命令行下的FOR具有更为严格而复杂的分析和替换特性。

  最后,不揣冒昧,再次提醒兄在提出问题时,能尽量不因自己的主观判断而影响全面而客观的描述问题,否则将有可能使解答者走入歧途。

[ Last edited by willsort on 2006-6-22 at 17:59 ]



※ Batchinger 致 Bat Fans:请访问 [讨论]批处理编程的异类 ,欢迎交流与共享批处理编程心得!
2005-5-26 00:00
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
GOTOmsdos
铂金会员

C++启程者


积分 5154
发帖 1827
注册 2003-7-18
状态 离线
『第 5 楼』:  

问题是换成D:\WBAT为当前目录,一样没有FOR后的文件,但却可以呀!怎么解释?

2005-5-27 00:00
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
willsort
元老会员

Batchinger


积分 4432
发帖 1512
注册 2002-10-18
状态 离线
『第 6 楼』:  

Re GOTOmsdos:  唯一的解释就是D:\WBAT下已有文件可以匹配s*.grp r*.idx的文件名。在这种情况下,FOR搜索的是D:\WBAT下的文件,但拷贝的却是D:\Legend下的文件。



※ Batchinger 致 Bat Fans:请访问 [讨论]批处理编程的异类 ,欢迎交流与共享批处理编程心得!
2005-5-28 00:00
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
GOTOmsdos
铂金会员

C++启程者


积分 5154
发帖 1827
注册 2003-7-18
状态 离线
『第 7 楼』:  

哇! willsort兄! 真是如你所说,D:\WBAT下确实有文件匹配那些文件集! 是我没注意到!那我再试..

2005-5-28 00:00
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
GOTOmsdos
铂金会员

C++启程者


积分 5154
发帖 1827
注册 2003-7-18
状态 离线
『第 8 楼』:  

C:\WBAT>for %a in (s*.grp r*.idx) do copy d:\legend\%a E:\legend /yFOR后文件集中如有*,如果前面没有路径就一定要在当前目录中找匹配文件,而后面却不需要处理这些文件,这算不算是BUG ?为什么一定要找到这些匹配文件呢? 我觉得应该设计成把FOR后文件集中的*也设计成字符串,在DO后,要处理他们时再确定路径,如前面给了路径,就没问题如没有给路径再在当前目录下找也不迟呀! 这不是作茧自缚吗?

2005-5-28 00:00
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
willsort
元老会员

Batchinger


积分 4432
发帖 1512
注册 2002-10-18
状态 离线
『第 9 楼』:  

Re GOTOmsdos:
  在我看来这是FOR的一个特性,因为设计者是有意这样实现的,而且FOR的设计思想是与你现在的实际应用有些偏差的。
  FOR真正重要的功能是实现文件的遍历,而非字符串的简单替换,能够在命令行简单地将文件名通配符解析为一个个单独的文件名进行分别处理,这应该FOR最主要的设计初衷,字符串替换只是附带实现的功能而已,而能够甄别文件名的有效性,也是其他字符串替换工具所不具备的特性;而要实现简单的字符串替换,那是可以不用FOR的,比如我经常使用的命令行参数遍历,它在此方面甚至比FOR灵活高效。
  就如你上面的代码,我建议不用FOR,直接用下面的句子也许更好些,虽然代码量增大了,但是可读性更高,而且因为它只调用了两次COPY命令,而使用了FOR它调用COPY的次数与匹配的文件总数相当,因而也可以节约一些系统资源。当然相对COPY这个“高耗能”操作来言,这个调用内部命令次数减少而节约的资源是微乎其微的,但是这个原理在其他操作中有可能起到很好的效果。
  if exist d:\legend\s*.grp copy d:\legend\s*.grp z:\legend
  if exist d:\legend\s*.grp copy d:\legend\r*.idx z:\legend

[此贴子已经被作者于2005-5-29 11:32:14编辑过]






※ Batchinger 致 Bat Fans:请访问 [讨论]批处理编程的异类 ,欢迎交流与共享批处理编程心得!
2005-5-29 00:00
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
GOTOmsdos
铂金会员

C++启程者


积分 5154
发帖 1827
注册 2003-7-18
状态 离线
『第 10 楼』:  

后来我就是用带%1的批处理完成的,但总是感觉FOR语句很简洁呀

2005-5-29 00:00
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
willsort
元老会员

Batchinger


积分 4432
发帖 1512
注册 2002-10-18
状态 离线
『第 11 楼』:  

Re GOTOmsdos:  我猜测不出你使用%1完成它的目的何在,难道你的程序不仅仅只是拷贝一些文件吗?不如贴出你现在的代码看看。



※ Batchinger 致 Bat Fans:请访问 [讨论]批处理编程的异类 ,欢迎交流与共享批处理编程心得!
2005-5-29 00:00
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
GOTOmsdos
铂金会员

C++启程者


积分 5154
发帖 1827
注册 2003-7-18
状态 离线
『第 12 楼』:  

是的,还要加上检测如下:file.bat:loop
if "%1"=="" goto end
rem md "%enddir%\%1" >nul
copy "%gamesave%\%1" z:\%gamedir% /yif not exist z:\%gamedir%\%1 goto fail
shift
goto loop
:fail
set addleg=fail:end
调用:file s*.grp r*.idx ........

2005-5-30 00:00
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
willsort
元老会员

Batchinger


积分 4432
发帖 1512
注册 2002-10-18
状态 离线
『第 13 楼』:  

Re GOTOmsdos:  似乎你要拷贝的文件还不止 s*.grp r*.idx,那么使用独立模块应该是更好的选择。  给你两个建议:    1、独立模块并非要独立批处理,除非你要在很多批处理中调用;    2、你的检测仅限于拷贝后,是否应该考虑拷贝前指定文件是否存在?



※ Batchinger 致 Bat Fans:请访问 [讨论]批处理编程的异类 ,欢迎交流与共享批处理编程心得!
2005-5-30 00:00
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
GOTOmsdos
铂金会员

C++启程者


积分 5154
发帖 1827
注册 2003-7-18
状态 离线
『第 14 楼』:  

是啊,我就是拷贝几个文件集,检查有没有成功,就完了,也不要多次调用的..既然用FOR,还要在文件集中加路径,或者临时改变当前目录,有点麻烦,那用带%1的循环来解决就很好已经解决啦!  而且我觉得已经比较简捷啦, 没必要再用别的方法了吧?

2005-5-30 00:00
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复

请注意:您目前尚未注册或登录,请您注册登录以使用论坛的各项功能,例如发表和回复帖子等。


可打印版本 | 推荐给朋友 | 订阅主题 | 收藏主题



论坛跳转: