[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖
看来for真的是个函数了,当初我就在纠结将for看成语块的时候,in前头的部分该理解成什么呢?现在用函数的观点来看,虽然“函数”是个比较万金油的概念,但确实比“语块”的说法更准确

TOP

本帖最后由 zm900612 于 2011-5-26 16:44 编辑

草就一个模型,就事论事,不考虑useback等因素,还有一些不用for的情况下不好处理的东西也一笔带过,比如tokens
  1. @echo off
  2. call :for /f "tokens=1* delims=:" %%a in ("%time%") do echo %%b
  3. pause&exit
  4. :for
  5. if %1==/f goto /f
  6. ...
  7. :/f
  8. set test=%2
  9. if "%test:~2%" neq "" set tokens=1* &set delims=: &shift /2
  10. set start=%2
  11. ...
  12. shift /3
  13. if "%~3" neq "%3" goto var
  14. if "%~3" leq " " goto command
  15. goto file
  16. ...
  17. :var
  18. set tmp=%~3
  19. setlocal enabledelayedexpansion
  20. set %%b=!tmp:*:=!
  21. echo !%%b!
  22. endlocal
  23. exit /b
复制代码

TOP

我在想,如果for是个函数的话,它大概分为几大子函数:无开关、/f、/l、/r、/d
而仔细回想一下,发现只要有无开关的for作为基础,就能降低其他几个开关实现的难度。
最有代表性的是for /l和for /f,举个例子
for /l %%a in (1 2 10) do echo %%a
::在这个(1 2 10)中,若不用变量通配替换,如何区分初始值、步数和终止点呢?若用for %%a in (1 2 10)...来判断呢?区分参数的工作一下轻松了许多

for /f "tokens=1* delims=:" %%a in ("123:345") do echo %%b
::for在这里如何去分别设置tokens=1* delims=:呢?我想,如果把无开关的for当成基石,那又降低了实现门槛:for %%a in (tokens^=1* delims^= do set %%a,值得一提的是,我原以为applda兄的那段代码之所以不需要加空格,是因为cmd在预处理时将参数划分好再加上空格(就像对重定向干的事一样),但是后来实验证明并非如此,对参数的划分是for命令(函数)自发的,仔细想想这也有道理,毕竟在cmd中,"tokens=1* delims=:"是以%2的形式传递给for命令(函数),cmd不会去解释参数中的参数,因为那在除了for以外的环境下都将是好心办坏事,所以for函数就和我们平时编写的函数一样,自己动手丰衣足食

TOP

本帖最后由 zm900612 于 2011-5-26 19:55 编辑

引申话题:
既然for是函数,那别的内部命令又是什么呢?
看来也是函数咯?如果这个说法成立,那其他内部命令和for和if命令之间的区别是什么呢?

其实现在想来,完全把for和if当成函数的观点也有一点瑕疵,我举个例子:
  1. call for %%%%a in ("123") do echo %%%%a
  2. call if exist %0 echo 123
  3. pause
复制代码
显示的是“'XX'不是内部或外部命令,也不是可运行的程序或批处理文件。”,而别的命令则不存在此问题,这是不是说明cmd中其实并不直接存在for这个模块呢?

TOP

楼上貌似是for的模型?
可惜我不懂编程,只能大概地猜下

TOP

个人认为/f开关是for所有开关中最重要的一个,对于新手甚至部分老手要掌握这个/f开关的所有参数及其用法是有一定难度的。。。

关于eol,usebackq,skip,tokens,delims这五个/f开关下的参数,记得cn-dos的9527有一篇 ...
batman 发表于 2011-5-25 19:30

基于for的参数不需要空格分隔的理论基础,老兄这说法也大有问题,而且哪怕用上空格来分隔,似乎也不惧:
  1. @echo off
  2. for /f "delims=, tokens=1,2 eol=e skip=1" %%a in ('
  3. "echo skip&echo eol&echo 显 示,不显示"
  4. ') do echo %%a
  5. pause
复制代码
该显示的仍然显示了,不该显示的也同样没有显示,并不因为“delims=,”后跟空格而造成误判。看来for对于参数的划分有点像cmd对于重定向的划分,虽然在cmd回显中看不到,但是我想,for对参数的划分应该也是和cmd同样的从预处理到执行的步骤:
1、转换分隔符为空格,如果不存在分隔符则自动加上空格(就像cmd会把“echo>nul 不显示”预处理成“echo 不显示 1>nul”一样)
2、读取参数#@!@@#¥!……

另外,顺便提一个疑惑,如果for真的是函数,如何解释for在语块中不能对其参数使用带有延迟性质的变量呢?

TOP

关键字又是什么概念?如果能弥补“函数论”的缺陷,我不介意叛变...

TOP

19楼的代码似是而非
又没有处理转义符号
不能作为for命令语法分析的参考

把cmd内部命令理解为函数未尝不可
但不要生硬套用函数模型来强解命令行分析

for和if不是关键字而是命令
官方文档提到的关键字
是f ...
qzwqzw 发表于 2011-5-26 21:29

似乎一步一步地明朗化了

TOP

我原以为,for是以类似%1的形式接受参数的,但是下面这个怪异现象又让我迷茫了:
  1. for /f "delims= "tokens^=2 %%a in ("haha test") do echo %%a
  2. ::正确
  3. for /f tokens^=2"delims= " %%a in ("haha test") do echo %%a
  4. ::出错
复制代码
第一条可以执行,的二条却出错,这就与call的情况不一样了,为什么呢?

TOP

47# zm900612


for /f "delims= ""tokens=1-3" %a in ("aa bb cc") do echo %a.%b.%c
这样不会报错,但结果是aa.%b.%c,好像tokens=2未起作用。

for /f "eol=a""delims= ""tokens=1-3" %a in ("aa bb cc") ...
powerbat 发表于 2011-5-27 19:22

我晕了,昨天只是想到call参数的特性,试了一下,没研究这么多。
佩服

TOP

返回列表