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

[文本处理] 批处理for命令的delims跟tokens位置互换探讨

我是做batman的题时遇到的,先来看两段代码:
代码1(from tab):
  1. @echo off
  2. setlocal enabledelayedexpansion
  3. for /f "tokens=1,2,3 delims=- " %%i in (a.txt) do (
  4.     for /f "tokens=1,2 delims= " %%a in (b.txt) do (
  5.         set var=%%a0000
  6.         set var=!var:~0,7!
  7.         if !var! geq %%i if !var! leq %%j if %%b neq %%k echo %%a %%b >>c.txt
  8.                                                    )
  9.                                                   )
复制代码

代码2(me):
  1. @echo off
  2. setlocal enabledelayedexpansion
  3. for /f "delims=-  tokens=1,2,3" %%i in (a.txt) do (
  4.       for /f "tokens=1,2 delims= " %%a in (b.txt) do (
  5.               set var=%%a0000
  6.               set var=!var:~0,7!
  7.               if !var! geq %%i if !var! leq %%j if %%b neq %%k echo %%a %%b >>c.txt
  8.                                                      )
  9.                                                   )
复制代码
观察发现,循环体没错,就第一个for循环处的delims跟tokens位置不一样,但是运行代码后就得出了两个不同的结果,代码1是正确的,代码2运行的结果却出错。
代码2结果:
  1. 721 古岳峰
  2. 721 淦田
  3. 721 白关
  4. 721 雷打石
  5. 723 砖桥
  6. 723 古岳峰
  7. 7257 仙井
  8. 7257 淦田
  9. 7257 县城
  10. 72581 淦田
  11. 72581 砖桥
  12. 7276 砖桥
  13. 7276 朱亭
  14. 7276 雷打石
  15. 7276 县城
  16. 7276 砖桥
  17. 7276 朱亭
  18. 7276 雷打石
  19. 7276 县城
  20. 728 朱亭
  21. 728 白关
  22. 728 砖桥
  23. 7296 朱亭
  24. 7348 淦田
  25. 7348 砖桥
  26. 7348 朱亭
  27. 7348 仙井
  28. 7373 雷打石
  29. 7373 古岳峰
  30. 7373 县城
  31. 7373 白关
  32. 7375 古岳峰
  33. 7375 淦田
  34. 7456 雷打石
  35. 7456 白关
  36. 7456 古岳峰
  37. 7473 淦田
  38. 7473 白关
  39. 7473 仙井
  40. 748 白关
  41. 748 仙井
  42. 7496 仙井
  43. 7496 白关
  44. 7496 县城
  45. 7496 雷打石
  46. 761 仙井
  47. 761 县城
  48. 761 白关
  49. 761 朱亭
  50. 7672 县城
  51. 7672 仙井
  52. 7693 县城
  53. 7693 仙井
复制代码

[ 本帖最后由 sgaizxt001 于 2010-1-25 03:30 编辑 ]

在来看两个代码:
代码3:
  1. @echo off
  2. setlocal enabledelayedexpansion
  3. echo 我想学批处理,遇到不懂我就发帖子,还请多多指教 >aa.txt
  4. for /f "tokens=1,2,3 delims=, " %%i in (aa.txt) do echo %%i %%j %%k
  5. pause
复制代码
代码4:
  1. @echo off
  2. setlocal enabledelayedexpansion
  3. echo 我想学批处理,遇到不懂我就发帖子,还请多多指教 >aa.txt
  4. for /f "delims=, tokens=1,2,3" %%i in (aa.txt) do echo %%i %%j %%k
  5. pause
复制代码
但是在这里,两个代码的执行结果却完全相同

[ 本帖最后由 sgaizxt001 于 2010-1-25 01:52 编辑 ]

TOP

继续测试,这次只简单修改代码1跟代码2,把if语句改为echo !var! %%a %%b %%i %%j %%k,用来看它的显示,来查找为什么代码2会出现错误。验证后发现代码2完全不能正确的取得%%k的变量,但是为什么代码1却能正确的取得%%k变量呢?
再继续,修改aa.txt的内容,改为:我想学批处理-遇到不懂我就发帖子 还请多多指教。同样的,把代码3跟代码4修改一下分隔符。然后运行,结果正确。是不是因为每一个变量就一句话,实际没有循环,所以不会出错呢?又或者是变量I,J,K的内容有猫腻呢?
继续测试,代码5:
  1. @echo off
  2. setlocal enabledelayedexpansion
  3. for /f "delims=-  tokens=1,2,3" %%i in (a.txt) do echo %%i %%j %%k
  4.       for /f "tokens=1,2 delims= " %%a in (b.txt) do echo %%a %%b
  5. pause
复制代码

经过测试,变量取值完全正确,那么问题出现在哪呢?代码2的循环操作跟代码1的完全一样,而且对于两个for语句来说,变量取得都没错啊,这到底为什么呢?

[ 本帖最后由 sgaizxt001 于 2010-1-25 03:27 编辑 ]

TOP

回复 2楼 的帖子

代码3和代码4  因为aa.txt内容没有空格 所以 "delims=, "  只有 " , " 起作用所以结果一样

把 tokens写在后面我也是跟batman学的, 至于为什么, 还不知道. 只管记住.
或者写成 "delims= ," 这样 把空格放前面 应该就没问题了.

TOP

但是参照代码1跟代码2,可以发现tokens写在前面能得到正确的结果,写在后面的反而错误

TOP

FOR命令空格和跳格做分隔符的区别及delims位置选择
http://www.bathome.net/thread-3770-1-1.html
命令行参考:hh.exe ntcmds.chm::/ntcmds.htm
求助者请拿出诚心,别人才愿意奉献热心!
把查看手册形成条件反射!

TOP

但是,我用代码5echo测试%%k变量否能获取正确的信息啊

TOP

原帖由 sgaizxt001 于 2010-1-25 01:55 发表
经过测试,变量取值完全正确,那么问题出现在哪呢?代码2的循环操作跟代码1的完全一样,而且对于两个for语句来说,变量取得都没错啊,这到底为什么呢?

其实,变量取值已经出错了
  1. for /f "delims=- tokens=1,2,3" %%i in (a.txt) do echo %%i %%j %%for /f "delims=-  tokens=1,2,3" %%i in (a.txt) do echo %%i %%j
复制代码
两个for语句的结果完全一样,也就是说%%k根本就取不到值。
个人理解,delims最好放在最后面。如果delims之后还有其他语句,例如tokens和skip,一旦分隔符中有空格,for语句都会理解成delims与其他语句的间隔。
  1. for /f "delims= - tokens=1,2,3" %%i in (a.txt) do echo %%i %%j %%k
复制代码
for语句会认为没有分隔符,但是- tokens=1,2,3这明显是for不能识别的,报错。
  1. for /f "tokens=1,2,3 delims=-  skip=4" %%i in (a.txt) do echo %%i %%j
复制代码
虽然有两个空格,但是for会认为这两个空格是delims与skip的间隔,所以分隔符只是-。

[ 本帖最后由 sysplay 于 2010-1-27 08:45 编辑 ]

TOP

返回列表