WINDOWS中的脚本 No.04
仔细考虑了一下,觉得之前的有些东西有必要着重地讲一下,那就是循环语句,以及经常使用的一些包装数据的东西,数组和集合。
数组,顾名思义,就是装一组数值的东西,你可以认为你家的冰柜F是一个大小为3的数组,最顶上的一格F(0)装的是蔬菜,是冷藏室,中间一层F(1)装的是冰棍,是冷冻室,最下面一格F(2)是掏炉灰的。这里可以看出如果变量F代表一个数组,那么它里面装的东西是有顺序的,我们把代表每个东西的顺序的序号叫做“下标”,下标是从 0 开始的,因此总是比通常说的“第几个”的几要小 1 ,数组变量后面跟对小括号里面是一个数字,这就代表数组中的某一个特定的数值,比如 F(0) 代表 F 的第一个东西,F(2) 代表第三个东西,F(3)是错误的,因为没有第四个。一种初始化一个数组的方法是利用Array函数直接赋值,比如冰柜
F = Array("冷藏室", "冷冻室", "炉灰坑")COPY
大家知道批处理里面的FOR循环语句有种语法是
[quoto]FOR %variable IN (set) DO command [command-parameters][/quoto]
这里的 set 就和数组的意思大概是一样的,当然了,不要因为他叫“数”组就认为里面的东西不一定全是数字,可以是任何类型的数据,比如字符,日期,甚至是任意的对象,显然叫“字符串组”、“日期组”甚至“东西组”是没有必要的,于是就沿用数组这个名字了。
VBS中比批处理便利的就是什么东西都能存到变量里,并且是个东西都会有然后想用的时候直接调变量。我们来看个例子,有三个人依次是张三李四王二麻子,现在要编一段代码分别显示他们的名字,然后指明第二个人是谁。
我们可能会写出如下的批处理代码:
| @echo off | | set names=张三 李四 王二麻子 | | for %%a in (%names%) do echo %%a | | setlocal enabledelayedexpansion | | set /a i=0 | | for %%a in (%names%) do ( | | set /a i+=1 | | if !i! EQU 2 echo 第二个人是%%a | | ) | | pause>nulCOPY |
与批处理的 for ... in () 相对应,在VBS中用 for each ... in 的格式可以遍历一个数组或者集合,代码如下:
| names = array("张三", "李四", "王二麻子") | | for each a in names | | wscript.echo a | | next | | a = names(1) | | wscript.echo "第二个人是" & aCOPY |
从这里可以看出,利用数组可以更加方便和准确地操作数据。
或许有人想到,for 有 /f 参数,直接用字符分隔的方式不就能获取第二个吗?
| @echo off | | set nameStr="张三 李四 王二麻子" | | for /f "tokens=1,2,3 delims= " %%a in (%nameStr%) do echo 第二个人是%%b | | pause>nulCOPY |
相对于批处理中这种用分隔字符分割一个字符串,得到几段字符串的办法,VBS中也有这种功能的函数Split,这是一个非常有用的函数,在我日常的实用中,数组一般都是用它创造出来的,因为他的返回值就是一个数组,代码如下
| nameStr = "张三 李四 王二麻子" | | | | | | names = Split(nameStr, " ") | | | | wscript.echo "第二个人是" & names(1)COPY |
这种方式中,批处理是变量名abcde依次往后排,而VBS是下标依次往后排,如果我们是要获取第 365 个人的名字呢?代表这个人名字的变量名是什么我不知道,但显然用数字下标的方式更合适。
批处理中for循环还有一种参数为 /L 的,格式为
[quoto]FOR /L %variable IN (start,step,end) DO command [command-parameters][/quoto]
在VBS中与此对应的格式是 for <variable> = <start> to <end> step <step>。
我们把之前的问题稍微改一改,最后不是“第二个人”,而是“第二到三个人”,那么又改怎么编码呢?如果用批处理我们可能需要再套一层循环,每次都判断是第几个:
| @echo off | | set names=张三 李四 王二麻子 | | for %%a in (%names%) do echo %%a | | setlocal enabledelayedexpansion | | | | for /l %%n in (2,1,3) do ( | | | | set /a i=0 | | for %%a in (%names%) do ( | | set /a i+=1 | | if !i! EQU %%n echo 第%%n个人是%%a | | ) | | ) | | pause>nulCOPY |
之所以会这样麻烦,是由于在批处理中我们不能直接使用那个set(集合,names)参数,而在VBS中我们已经知道可以根据下标取它里面的某个值,因此就要简单很多了:
| names = array("张三", "李四", "王二麻子") | | for each a in names | | wscript.echo a | | next | | | | | | | | for n = 1 to 2 step 1 | | a = names(n) | | | | wscript.echo "第" & (n+1) & "个人是" & a | | nextCOPY |
还有一对与数组相关的可能要经常使用到的函数是 UBound 和 LBound,分别是取一个数组下标的最大值和最小值,以我们的冰柜为例,UBound(F) 的值是 2,LBound(F) 的值是 0 ,于是如果来个新要求,“在不知道总共有多少人的情况下,列出所有人的名字并指出他们分别是第几个”,我们可以写出如下代码:
| names = array("武大", "张三", "李四", "王二麻子") | | s = lbound(names) | | e = ubound(names) | | for n = s to e | | a = names(n) | | wscript.echo "第" & (n+1) & "个人是" & a | | nextCOPY |
还有一种叫做集合的东西,其实也很好理解,集合嘛,就是一堆东西放在一起,那他跟一组东西有什么区别呢?一组是有序号的,一堆没有序号,仅此而已。所以如果要把 for 循环用在集合上,那么就只能用 for each ... in 的方式了,这个跟数组差不多,就先不讲了。
我们来看个数组应用的例子吧,有些在批处理中很难处理的问题,在VBS中由于设计的不同,就很容易解决了。
批处理中delims该怎样使用多个字符为分隔符?
http://www.bathome.net/viewthread.php?tid=7596
我之前以为批处理中能行,但是经人举例,发现错了,但是在VBS脚本中决绝非常容易。就用我们之前的 Split 函数。
比如要用 ab 作为分隔符分割字符串 aabbabaabbceabd
| str = "aabbabaabbceabd" | | delims = "ab" | | arr = split(str, delims) | | s = lbound(arr) | | e = ubound(arr) | | wscript.echo "总共分割成了" & (e+1) & "段。" | | for n = s to e | | a = arr(n) | | wscript.echo "第" & (n+1) & "段是" & a | | nextCOPY |
|