中国DOS联盟论坛

中国DOS联盟

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

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

游客:  注册 | 登录 | 命令行 | 会员 | 搜索 | 上传 | 帮助 »
作者:
标题: 一段批处理不解,求释义? 上一主题 | 下一主题
jingyu57
初级用户





积分 32
发帖 10
注册 2008-6-19
状态 离线
『楼 主』:  一段批处理不解,求释义?

@echo off
set "ext=%~x1"
set pic=.BMP,.JPG,.PNG,.GIF,
set doc=.doc,.txt,.xls,

::利用变量替换判断文件属于哪一组
call set tmp=%%pic:%ext%,=%%
if not "%tmp%" == "%pic%" goto pic

call set tmp=%%doc:%ext%,=%%
if not "%tmp%" == "%doc%" goto doc

goto :EOF

:pic
echo 文件为图片文件。
goto :EOF

这是向论坛某位版主求助时发给我的解决方案。无奈水平有限,看不懂红色部分含义。那位热心的版主貌似很忙,一直不见露面,同时考虑到这个批处理实在经典,用到了变量替换判断(而且是以数组的形式出现),对像我一样的菜鸟不无帮助。特请高手释义,谢谢!

2008-7-16 16:06
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
HAT
版主





积分 9023
发帖 5017
注册 2007-5-31
状态 离线
『第 2 楼』:  

搜索"变量延迟扩展"
搜索“变量截取”
搞清楚这两个问题,可以让自己的批处理水平提高一个层次。

   此帖被 +1 点积分    点击查看详情   
评分人:【 jingyu57 分数: +1  时间:2008-7-16 20:03




2008-7-16 16:16
查看资料  发短消息 网志   编辑帖子  回复  引用回复
jingyu57
初级用户





积分 32
发帖 10
注册 2008-6-19
状态 离线
『第 3 楼』:  

多谢楼上的。授人以鱼不如授之以渔。
苦于一直找不到搜索的对象。这就去看看。

2008-7-16 16:35
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
quya
高级用户

五星老土


积分 558
发帖 172
注册 2003-2-9
来自 江苏
状态 离线
『第 4 楼』:  

我来解释一番吧。

说实话,我也是菜鸟,菜鸟即使搜索了有关主题也不一定看得懂,因为没有具体的实例可供参考,需要自己慢慢摸索,这是一个相当长的痛苦过程。

先假定这个例子中的文件名为 TESTFILE.CMD

当键入 Testfile.cmd xxx.bmp 的时候, 执行结果会显示 “文件为图片文件。”

@echo off
set "ext=%~x1"  结果是 set ext=bmp, %1就是 xxx.bmp, %~x1 就是只取 %1的扩展名

set pic=.BMP,.JPG,.PNG,.GIF,
set doc=.doc,.txt,.xls,

::利用变量替换判断文件属于哪一组
call set tmp=%%pic:%ext%,=%%        简化下就是 set tmp=%pic:bmp,=% 执行结果变成 set tmp=.JPG,.PNG,.GIF, 这是把bmp,替换成空值, 一个简单的例子 tmp=%pic:.=*%, 就是把PIC变量中的"."变成"*", pic=*BMP,*JPG,*PNG,*GIF,
if not "%tmp%" == "%pic%" goto pic 既然替换成功,那么tmp,pic 2个值就不等了,说明之前输入的文件是 BMP文件, 也就是图形文件。至于CALL,就是预先把 %ext%先替换成 扩展名,这里的值是:"bmp". 有点延迟变量的概念。

call set tmp=%%doc:%ext%,=%%        同上, 如果暂时对CALL疑惑,先知其然不知其所以然吧,我不懂的地方也是先记住了再说,或者把call拿掉,可以观察下运行结果有什么不同。

if not "%tmp%" == "%doc%" goto doc
goto :EOF

:pic
echo 文件为图片文件。
goto :EOF

   此帖被 +1 点积分    点击查看详情   
评分人:【 jingyu57 分数: +1  时间:2008-7-16 20:03




我怎么找不到一个比我注册日期早的人? 难道我是传说中的超级管理员? 其实我只是个潜水冠军而已.
2008-7-16 16:45
查看资料  发短消息 网志   编辑帖子  回复  引用回复
zhouhuang
初级用户




积分 56
发帖 28
注册 2008-7-5
状态 离线
『第 5 楼』:  !!

顶顶!!
又学到一招!!谢谢!!

2008-7-16 20:37
查看资料  发送邮件  访问主页  发短消息 网志   编辑帖子  回复  引用回复
jingyu57
初级用户





积分 32
发帖 10
注册 2008-6-19
状态 离线
『第 6 楼』:  

多谢楼上quya潜水兄的一番细心解释。
其实这个批处理里面最不懂的就是:

::利用变量替换判断文件属于哪一组
call set tmp=%%pic:%ext%,=%%
if not "%tmp%" == "%pic%" goto pic

自己摸索得比较慢,看了你的解释有种恍然大悟的感觉。

结合plp626兄的这个启蒙帖子:http://www.cn-dos.net/forum/viewthread.php?tid=37382   现在我能理解到这个程度:

依照quya兄的指点,先把call set tmp=%%pic:%ext%,=%%分解一下,变为简单一些的语句,或者说把它分解成几步来执行:
1. %ext%,=%%,即将当前文件扩展名替换为空;
2.%%pic:%ext%,=%%,先将%pic后面的%ext%换成空,然后再来对%pic%进行处理,那么存在两种情况:
      a. 如果%ext%恰好是图片格式如.bmp,.jpg,那么这种替换就能影响到%pic%,即成功替换%pic%里面的【%ext%,】(这个:很关键啊!!!),而【%ext%,】已经在前面替换结果为空,所以实际上就相当于在%pic%里去掉【当前文件扩展名,】,比如【.bmp,】(注意这个,);
      b. 如果%ext%不是图片格式,比如.txt,.doc,这种格式不在%pic%这组,显然也就不能影响到%pic%这组(虽然%ext%仍然已经被替换为空,但是由于它已经不在%pic%这组,所以%pic%这组中的任何字符或者字符串都不会被替换),根据批处理的逐行运行特性,下面会继续进行后面的判断等操作;
3.有了前面的判断,现在就好办多了。只需要根据上面判断+替换的结果和原来的%pic%或者%doc%等做个比较,判断是否有改变,如有,则进行一次跳转,否则继续运行后面的语句,依此运行下去,就能达到我们的目的了。这部分比较简单,就不再赘言了。
至于CALL,是用来变量延迟的,这个之前已经有所了解。

不知道我上面的理解还有没有错误或者纰漏的地方,如有望各位大侠不吝赐教。
现在回过头来想想,其实这个批处理很精彩啊!巧妙的运用了一次替换+判断来完成了批处理里不易实现的逻辑“或”(至少表面上不太容易实现,偶是菜鸟,别拍砖~~),通过这次提问,对set变量截取了解加深不少,同时也学到了变相解决一些问题的思路和方法。感谢那位斑斑和各位朋友的帮助!特别是quya兄的精彩解释和plp626兄的启蒙教程!DOS联盟正是因为许许多多这样的朋友而精彩!

   此帖被 +8 点积分        点击查看详情   
评分人:【 moniuming 分数: +8  时间:2008-7-16 22:19


2008-7-16 20:51
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
jingyu57
初级用户





积分 32
发帖 10
注册 2008-6-19
状态 离线
『第 7 楼』:  

多谢moniuming 兄加分鼓励。
仔细一看,发现quya兄解释里面有一处疏忽。
@echo off
set "ext=%~x1"  结果是 set ext=bmp, %1就是 xxx.bmp, %~x1 就是只取 %1的扩展名。

这里结果应该是set ext=.bmp, %1即当前文件,%~x1取得%1的扩展名时还有一个“.”。
采用echo "%~x1"做实验,得到的也是.bmp。

此外发现一个有趣的现象,并得出一个结论:
CMD判断扩展名的方法并不完美。
个人猜测CMD是以文件(文件夹)名最后一个“.”作为分隔符,取此“.”后面的字符串+这个“.”共同组成扩展名。
这样对于判断文件是没有问题的,但是如果和文件夹混在一起,就判断不清了。
为验证想法,做试验如下:
新建一个批处理:
@echo off
if "%~x1"=="" goto no
echo "%~x1"
pause
:no
echo  这个一个文件夹!
pause
如果是普通文件夹,拖放到这个批处理上面会显示”这是一个文件夹!“一点问题没有;
但是如果我现在建一个文件夹,取名为“test.txt.jpg"
那么CMD会取得扩展名.jpg,然而事实上文件夹是不存在扩展名一说的,从而验证了我前面的猜测是对的,即CMD的扩展名判断方法并不完美。
此外也搜到了一些别的脚本取扩展名的方法,比如VBS和JS,似乎都是用最后一个”.“作为分隔符判断,同样也必然存在这种局限性。有没有别的更完美的方法呢?
我们拭目以待,期待高手的出现!

2008-7-17 08:00
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
HAT
版主





积分 9023
发帖 5017
注册 2007-5-31
状态 离线
『第 8 楼』:  

区分文件夹和文件的方法有很多,为什么偏偏要使用扩展名来判断呢?



2008-7-17 09:32
查看资料  发短消息 网志   编辑帖子  回复  引用回复
jingyu57
初级用户





积分 32
发帖 10
注册 2008-6-19
状态 离线
『第 9 楼』:  



  Quote:
Originally posted by HAT at 2008-7-17 09:32 AM:
区分文件夹和文件的方法有很多,为什么偏偏要使用扩展名来判断呢?

愿闻其详。
如果方便的话麻烦HAT兄给出一些思路或者搜索的关键词。
偶是菜鸟,目前想到的就是根据扩展名判断。见谅!

2008-7-17 11:02
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
jingyu57
初级用户





积分 32
发帖 10
注册 2008-6-19
状态 离线
『第 10 楼』:  

通过关键词“文件夹”居然搜到了。DOS联盟果然强大。
分享一下:
@echo off
dir/ad "%1">nul 2>nul && goto no
echo "%~x1"
pause
:no
echo  这个一个文件夹!
pause

妙哉!
Thank you HAT!

2008-7-17 11:21
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复

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


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



论坛跳转: