Board logo

标题: [文本处理] 【已解决】批处理for中双百分号后字母改为数字之后不能正常调用 [打印本页]

作者: jackerloo2009    时间: 2009-5-17 10:55     标题: 【已解决】批处理for中双百分号后字母改为数字之后不能正常调用

  1. 308\993\238\900\946\728\446\566\674\625\528\552\728\190\797\680\509\699\663\915\109\727\110\851\237\271\636\154\815\829\467\261\703\989\105\806\821\342\388\769\425\363\732\420\522\411\670\441\618\242\
复制代码
这是456.txt文本
  1. @echo on
  2. for /f "tokens=1-12 delims=\" %%1 in (456.txt) do echo %%1 %%2 %%3 %%4 %%5 %%6 %%7 %%8 %%9 %%10 %%11 %%12
  3. pause
复制代码
今天突发奇想测试用数字代替a-z,取值1-12结果如下
  1. 308 993 238 900 946 728 446 566 674 3080 3081 3082
复制代码
观察发现1-9正常,10,11,12只是取%%1的结果后面附加了0,1,2
然后想将%%1 %%2 %%3 %%4 %%5 %%6 %%7 %%8 %%9 %%10 %%11 %%12可不可以赋值,然后调用,代码如下
  1. @echo off
  2. del 789.txt
  3. @(for /l %%a in (1,1,12) do echo %%%%%%a>>789.txt)
  4. setlocal enabledelayedexpansion
  5. @(for /f %%b in (789.txt) do (
  6. @set "str=!str!%%b "
  7. )
  8. )
  9. @(for /f "tokens=1-12 delims=\" %%1 in (456.txt) do echo !str!)
  10. pause
复制代码
上面代码虽然执行了,但是并没有调用,又测试了以下的代码
  1. @echo off
  2. del 789.txt
  3. @(for /l %%a in (1,1,12) do echo %%%%a>>789.txt)
  4. setlocal enabledelayedexpansion
  5. @(for /f %%b in (789.txt) do (
  6. @set "str=!str!%%b "
  7. )
  8. )
  9. @(for /f "tokens=1-12 delims=\" %%1 in (456.txt) do echo !str!)
  10. pause
复制代码
结果还是不调用,最后又更改了,将!!改成了%%,代码如下
  1. @echo off
  2. del 789.txt
  3. @(for /l %%a in (1,1,12) do echo %%%%a>>789.txt)
  4. setlocal enabledelayedexpansion
  5. @(for /f %%b in (789.txt) do (
  6. @set "str=!str!%%b "
  7. )
  8. )
  9. @(for /f "tokens=1-12 delims=\" %%1 in (456.txt) do echo %str%)
  10. pause
复制代码
这次却成功调用了我的思路,有些不明白的是调用set的赋值,不是用!!,这为什么是%%,而且789.txt不是%%1这样的,而是%1
然后它调用才成功的!
望各位高人指点!

[ 本帖最后由 jackerloo2009 于 2009-5-18 12:23 编辑 ]
作者: namejm    时间: 2009-5-17 11:01

  提供一点思路:在批处理中,%0~%9属于默认的形式参数,用于引用特殊的内容,具体而言,%0表示批处理文件本身,可以直接引用;%1~%9表示第1~9个参数,常用于call语句的调用,比如在使用了 call :test a b c 之后,test标签段中的%1~%3将分别表示a、b、c,%4~%9为空值,而无论是%1还是%11还是%111,都会优先解析%1,并认为是%1之后跟了0个或多个字符。
作者: jackerloo2009    时间: 2009-5-17 11:48

原帖由 namejm 于 2009-5-17 11:01 发表
  提供一点思路:在批处理中,%0~%9属于默认的形式参数,用于引用特殊的内容,具体而言,%0表示批处理文件本身,可以直接引用;%1~%9表示第1~9个参数,常用于call语句的调用,比如在使用了 call :test a b c 之 ...


那就是%%1 这样的它也当做%1了?
可是我测试
  1. @echo off
  2. del 789.txt
  3. @(for /l %%a in (1,1,12) do echo %%%%%%a>>789.txt)
  4. setlocal enabledelayedexpansion
  5. @(for /f %%b in (789.txt) do (
  6. @set "str=!str!%%b "
  7. )
  8. )
  9. @(for /f "tokens=1-12 delims=\" %%1 in (456.txt) do echo %str%)
  10. pause
复制代码

得到的结果是多一个%,如下:
  1. %308 %993 %238 %900 %946 %728 %446 %566 %674 %3080 %3081 %3082
复制代码

就像 echo %%%1% 只是 %  %%1  %把外面脱去%%1然后把%1单独看做一个值这样?%1为空所以只显示一个% ?
可是这个我就难理解了
  1. for /f "tokens=1-12 delims=\" %%1 in (456.txt) do echo %%1 %%2 %%3 %%4 %%5 %%6 %%7 %%8 %%9 %%10 %%11 %%12
复制代码

它为什么不显示%308呢?
作者: netbenton    时间: 2009-5-17 13:35

单个%号,最先匹配后面的第一个数字,为真,则为参数:%0,%1~%9
为假时再找下一个%,找到后,把两个%%间的字符作为变量:%abc%
同一行后面不再有%了,就直接丢掉,不进行任何操作。

两个%%连着时,直接丢掉一个,再重新开始另一组匹配

经过上面的预处理后,在for 里面,若遇到%,则与后面的一个字符组成for变量,%a[只是一个字符]
如果存在相应的for令牌%a,则进行变量替换,如果没有,则值不变,仍为:%a

所以%%12,只匹配%1为for 变量,后面2与之没有关系
作者: SunTB    时间: 2009-5-17 21:20

进来学习了  有高手点评又能多学习点
作者: jackerloo2009    时间: 2009-5-18 08:33

谢谢各位的指点
我想我明白了如果是普通的赋值调用,调用要原原本本引用赋值
但是以上我测试的例子出现了特殊符号%
就如同echo  %%%a% ==%    echo %%a% == %a 一样的例子,它调用遵循了这个原则!
版主结了吧
作者: Batcher    时间: 2009-5-18 09:44     标题: 回复 6楼 的帖子

为啥不自己结,非得让版主结?
作者: jackerloo2009    时间: 2009-5-18 12:25     标题: 回复 7楼 的帖子

这个我加【已解决】提示超过60个字符。。。只好在保证标题原意不变的情况下去掉了一些的,了,才算ok
作者: wxcute    时间: 2009-5-18 12:38

参阅:[灌水]难看的 for 语句
http://bbs.bathome.net/viewthread.php?tid=2788

%%9 之后是 %%: %%; %%^<
作者: jackerloo2009    时间: 2009-5-18 13:17     标题: 回复 9楼 的帖子

谢谢了,难怪我自己测试的时候中途指定%%A,它竟然也有调用结果,原来它也有排位哦!只是如此说来你的解释是最正确的!
为了不误导大家!最后在这里重新说明问题,这里%%1并不是脱掉%是%1的问题,而是在ASCII中有一个字符顺序,都是逻辑递增的顺序,只要遵循ASCII这个顺序,调用就有效,我是从十进位047指向的/字符开始调用的,只是部分特殊字符牵涉到批处理特殊字符需要加^转义,请看以下代码
  1. for /f "tokens=1-26 delims=\" %%^/ in (456.txt) do echo %%^/ %%0 %%1 %%2 %%3 %%4 %%5 %%6 %%7 %%8 %%9 %%: %%; %%^< %%= %%^> %%? %%@ %%A %%B %%C
复制代码
结果成功echo了如下
  1. 308 993 238 900 946 728 446 566 674 625 528 552 728 190 797 680 509 699 663 915 109
复制代码
ASCII表如下
  1. ASCII 码 字符   ASCII 码 字符   ASCII 码 字符   ASCII 码 字符
  2. 十进位 十六进位   十进位 十六进位   十进位 十六进位   十进位 十六进位
  3. 032  20        056  38  8    080  50  P   104  68  h
  4. 033  21  !     057  39  9   081  51  Q   105  69  i
  5. 034  22  "     058  3A  :   082  52  R   106  6A  j
  6. 035  23  #    059  3B  ;   083  53  S   107  6B  k
  7. 036  24  $    060  3C  <   084  54  T   108  6C  l
  8. 037  25  %   061  3D  =   085  55  U   109  6D  m
  9. 038  26  &   062  3E  >   086  56  V   110  6E  n
  10. 039  27  '     063  3F  ?   087  57  W   111  6F  o
  11. 040  28  (    064  40  @   088  58  X   112  70  p
  12. 041  29  )    065  41  A   089  59  Y   113  71  q
  13. 042  2A  *   066  42  B   090  5A  Z   114  72  r
  14. 043  2B  +   067  43  C   091  5B  [   115  73  s
  15. 044  2C  ,   068  44  D   092  5C  \   116  74  t
  16. 045  2D  -   069  45  E   093  5D  ]   117  75  u
  17. 046  2E  .   070  46  F   094  5E  ^   118  76  v
  18. 047  2F  /   071  47  G   095  5F  _   119  77  w
  19. 048  30  0   072  48  H   096  60  `   120  78  x
  20. 049  31  1   073  49  I   097  61  a   121  79  y
  21. 050  32  2   074  4A  J   098  62  b   122  7A  z
  22. 051  33  3   075  4B  K   099  63  c   123  7B  {
  23. 052  34  4   076  4C  L   100  64  d   124  7C  |
  24. 053  35  5   077  4D  M   101  65  e   125  7D  }
  25. 054  36  6   078  4E  N   102  66  f   126  7E  ~
  26. 055  37  7   079  4F  O   103  67  g   127  7F   
复制代码
再次感谢楼上wxcute给的指引!

[ 本帖最后由 jackerloo2009 于 2009-5-18 13:41 编辑 ]
作者: netbenton    时间: 2009-5-18 19:13

还有一点,一个for 最大可用的令牌变量为31个,超过的无效
作者: jackerloo2009    时间: 2009-5-18 19:40     标题: 回复 11楼 的帖子

多谢楼上完善!论坛真的是个好地方,真正意义上诠释了不积小流无以成江海的道理!




欢迎光临 批处理之家 (http://www.bathome.net/) Powered by Discuz! 7.2