[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖
原来大牛也有短脚的地方呀(不生气吧)...
我认为预处理的本质之一是:
%1>%1%>%%1>!1!
::翻译过来是cmd参数(包括call出来的参数)优先级最高,一出现就会被预处理为常数,优先级最高;其次是未使用变量延迟的%str%变量,它是在解释语块之前进行的;再次是for中的参数%%a,在每次循环之初被解释;最后是变量延迟!str!,优先级比语句的分隔符(&、&&、|、||、"等)还低,优先级仅高于重定向(重定向是否该归到语句之中呢?我感觉可能用cmd来解释重定向比较合理吧,如果真是如此,重定向的优先级必然高于语句本身)。
所以楼主出现这种“诡异”症状的根本原因是call之后,cmd先解释了%1,再解释了%1%,然后才执行echo,由于标签不能位于括号之间(根本原因也与预处理的优先级有关),所以用%~1这种形式应该是无解的,建议不用%1,改用变量延迟或者for传递参数。
1

评分人数

    • namejm: 分析很深入技术 + 1

TOP

本帖最后由 zm900612 于 2011-4-14 13:54 编辑

比较厌恶goto和call,秀一下疯狂的for嵌套,将tokens无限拓展:
  1. @echo off&SetLocal EnableDelayedExpansion
  2. for %%i in (*.xml) do (
  3. for /f "useback" %%a in ("%%i") do (
  4. set tmp=%%i
  5. for /l %%l in (1 1 1000) do (
  6. for /f "tokens=1* delims=>" %%a in ("!tmp!") do (
  7. echo %%b
  8. set "tmp=!tmp:<*=!"&set "tmp=!tmp:<*=!"
  9. pause
  10. rem 不断循环,直到轮空
  11. )
  12. )
  13. )
  14. )
复制代码

TOP

还有,既然问题都是出在预处理机制对百分号产生误会上,那是否可以考虑先替换全部百分号为特殊字符,显示时再替换回来呢?
我感觉最讨厌的特殊字符不是百分号,而是感叹号,尤其是在for中...

TOP

本帖最后由 zm900612 于 2011-4-14 20:46 编辑

5# lllsoslll


“那么cmd在解释道call:... 这条语句时,会对%%j再次做预处理”,对这个观点我不敢苟同,我认为问题不是处在跳转到标签之前,而是之后,更明确地说,错误是出在解释%1之后紧跟着解释了空变量。
至于call echo %%a...这样的用法之所以能对变量进行二次扩展,我认为不是call本身对其进行解释,而是call一个命令时执行了cmd /c,由cmd去解释并运行它,我相信微软的程序员也遵循从简原则,不会在一个cmd中专门为call再定做一个专门的解释模块。至于for和if不能被call,我只有一个模糊的看法,就是可能是因为for和if可以包含子语句,call也许不能执行语句中的子语句,所以不支持if和for...

TOP

本帖最后由 zm900612 于 2011-4-15 12:54 编辑
说了这么一大堆,很多人看帖还不知是怎么回事,我来做个小总结,
==============================
楼主说的莫名丢失字符,,如我11楼所说
就是在cmd在预处理的时候会把%好冒号:之间的字符也当做变量来扩充,所以后 ...
lllsoslll 发表于 2011-4-15 00:30

确实,我想得不够深入,做了个实验,证明call确实在调用标签之前就已经解释了变量:
  1. @echo off
  2. set #=前
  3. prompt 此处修改了变量:
  4. ::本人比较喜欢玩,嘿嘿
  5. for %%a in (%%#%%) do (
  6. call echo for中call前 #=%%a
  7. echo ______________
  8. call :echo %%a
  9. )
  10. echo;&pause
  11. exit
  12. :echo
  13. echo;&echo call中set前 #=%1
  14. echo on
  15. set #=后
  16. @echo off
  17. echo;&echo call中set后 #=%1
复制代码
几乎不用call,所以以前没研究到这程度。sos兄功力真深厚啊,膜拜一下。
看来误区还是要在讨论中容易被发现和纠正啊
1

评分人数

TOP

至于!的问题,因为楼主的xml中并没有声明元素,所以这个顾虑可有可无,特殊情况下当然要考虑特殊字符,但是一般情况下够用就可以了吧...

TOP

返回列表