|
|
发表于 2011-10-8 01:29:18
|
显示全部楼层
再谈谈FOR的静态部分和动态部分。
-
- FOR /F ["options"] %variable IN (file-set) DO command [command-parameters]
复制代码
在FOR中,有几个地方是FOR的基本语法,不能改变:
1、FOR /F 静态部分
开头表明FOR命令,/F参数,用以区分其他命令和其他参数。
2、["options"] 动态部分
选项可选,并且部分要求高,要求顺序等,而部分要求不高,可以省略空格。我想,在FOR读到此处时,此处类似于一个FOR命令:
- for /f "tokens=1,2* delims=, " %%a in ("tokens=1,2,3 delims=, ") do echo %%a %%b
复制代码
提取选项关键词和数值,然后进行核对和处理。
选项外的双引号只是一种便于识别的辅助符号:
- C:\>for /f "tokens=1" %i in ("4 2 3")do @echo %i
- 4
- C:\>for /f tokens^=1 %i in ("4 2 3")do @echo %i
- 4
复制代码
而使用转义符才是根本,可能在使用多个转义符时,顾及麻烦,便舍弃转义符而偏爱双引号。而且,在编程过程中,使用双引号引住全部选项也符号常理。
为什么要进行转义呢,可能涉及到一些分隔符之类的特殊符号的处理。
3、变量%variable 动态部分
变量也是一个可以改变的部分。%%a批处理,%a命令提示符。批处理是一种脚本,%%a最终需要转化%a给cmd.exe处理。
一般输入变量能改变的较少,主要是输入变量前后要使用分隔符,不能与参数和IN连在一起。
4、in 静态部分
5、(file-set) 动态部分
集合可以是命令、路径和字符串。
6、DO 静态部分
7、command [command-parameters] 动态部分
整个下来:
FOR /F 动态选项 动态变量%%a in (动态集合) do 动态命令
FOR——(附加参数)——IN——(指明集合对象)——do——(指明动作)
静态部分是指不能改变的FOR的结构,它们之间必须使用分隔符(而不仅仅是空格,还包括其他默认的分隔符),否则出错。
动态部分是指可以选择的各个参数、变量、对象、动作等,可以自由改变,它们之间有些不必用分隔符。
-
- for /f ,%%a, ,,in("你好") do echo %%a
复制代码
看来默认分隔符在FOR当中是一个比较普遍适用的。
来猜测一下FOR的大概过程:
在命令窗口时代,输入%%a是要比输入%a要吃力的,而到了脚本时代,难道编程的大哥不怕麻烦了吗?估计从脚本转入cmd.exe执行时,有一个丢失百分号的问题(脱层)。为何会丢失呢?是否是与DOS执行区别?如果无法执行也不必做区别的,原因需要资料方可了解。
获得代码后,批处理开始获取执行顺序,预处理一定行数的代码,我们暂且定位十行吧,为什么不是全部一个bat都预处理呢?因为当它遇到一个几十M的批处理时(不要怀疑这个大的BAT,做程序要有这个考虑)如果全部预处理完的话,估计要花费相当多的时间。而实际上,我们打开一个比较大的批处理,一般不会出现卡住的情况。也或许它获得一行处理一行,预处理只是对一行内的命令进行处理而已。这个不好解释。
然后到获得具体的命令,比如FOR的,以“FOR”这个词语开头的一行代码。获得这行代码后分析它是独立的一行,还是有&连接的多个命令。但是,按照我的实践理解,FOR命令在遇到“FOR”并一路按照FOR的语法来判断这个FOR是否合法,从FOR到/F到选项到输入变量……,只要中间出现一个问题,批处理马上退出。实际上也是这样,所以,批处理的预处理只是针对类似FOR一类的命令,针对执行到的某一行,而非全部命令。因此,如果批处理真的是只按照FOR命令的语法从左到右进行判断,一旦遇到问题马上停止,那么,在没有判断一条完整的代码的情况下,也就是当FOR命令只执行到IN的位置,因为IN和括号连到一起了,发生错误,这时,批处理怎么知道命令是否正确呢?或者,命令是怎么区分出FOR、/F、tokens=、delims=等等命令、参数、选项、变量、符号等?这时,基本的语法结构就发挥很大的作用了,除此之外,利用分隔符可以很好的处理这些元素之间的距离和关系。分隔符的作用就是用来区分元素之间的,如果没有分隔符,容易致使两个命令或参数混淆。但我们也发现,tokens=1delims=m,这里的两个选项搅合到一起了,FOR还是能够认出他们。这么说,获得关键词这时就发挥作用了。比如“tokens=1-3delims=:”这个是正确的,但是“tokens=d1-3delims=:”“tokens=1-3ddelims=:”“tokens=1=3delims=:”“tokens=1-3,8delims=:”等都是错的。这就证明了,FOR是直接提取这两个选项的。
在处理完参数、输入变量之后,就到集合了,集合的处理存在预处理,它有可能是字符串,也可能是路径、命令之类的,特别是命令,需要预先处理,那么,这里就存在一个暂停,FOR暂停,等待集合中的命令先执行。而在这些命令执行前,FOR会先检查代码的是否符合语法。
至于到了DO后面的组合,这个也和集合差不多,存在一个暂停、预处理的过程。
因此,FOR的执行,首先检查是否合乎语法,第二预处理是否能够成功执行,第三才是真正的回显执行过程。
FOR和CALL、goto loop等差不多,只是他将一个重复的动作放到了FOR之中,使得代码更加简便,效率更高。 |
|