WINDOWS中的脚本 No.04
仔细考虑了一下,觉得之前的有些东西有必要着重地讲一下,那就是循环语句,以及经常使用的一些包装数据的东西,数组和集合。
数组,顾名思义,就是装一组数值的东西,你可以认为你家的冰柜F是一个大小为3的数组,最顶上的一格F(0)装的是蔬菜,是冷藏室,中间一层F(1)装的是冰棍,是冷冻室,最下面一格F(2)是掏炉灰的。这里可以看出如果变量F代表一个数组,那么它里面装的东西是有顺序的,我们把代表每个东西的顺序的序号叫做“下标”,下标是从 0 开始的,因此总是比通常说的“第几个”的几要小 1 ,数组变量后面跟对小括号里面是一个数字,这就代表数组中的某一个特定的数值,比如 F(0) 代表 F 的第一个东西,F(2) 代表第三个东西,F(3)是错误的,因为没有第四个。一种初始化一个数组的方法是利用Array函数直接赋值,比如冰柜
- F = Array("冷藏室", "冷冻室", "炉灰坑")
复制代码
大家知道批处理里面的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>nul
复制代码
与批处理的 for ... in () 相对应,在VBS中用 for each ... in 的格式可以遍历一个数组或者集合,代码如下:
- names = array("张三", "李四", "王二麻子")
- for each a in names
- wscript.echo a
- next
- a = names(1) '第二个人的下标为 1
- wscript.echo "第二个人是" & a
复制代码
从这里可以看出,利用数组可以更加方便和准确地操作数据。
或许有人想到,for 有 /f 参数,直接用字符分隔的方式不就能获取第二个吗?
- @echo off
- set nameStr="张三 李四 王二麻子"
- for /f "tokens=1,2,3 delims= " %%a in (%nameStr%) do echo 第二个人是%%b
- pause>nul
复制代码
相对于批处理中这种用分隔字符分割一个字符串,得到几段字符串的办法,VBS中也有这种功能的函数Split,这是一个非常有用的函数,在我日常的实用中,数组一般都是用它创造出来的,因为他的返回值就是一个数组,代码如下
- nameStr = "张三 李四 王二麻子"
- ' 指明分割字符串 nameStr,分隔字符(或者叫界定)是空格 " ",
- ' 并将返回的数组存放到变量 names 中
- names = Split(nameStr, " ")
- ' 稍微一想,分割出来的数组中的第二段就是我们要的
- wscript.echo "第二个人是" & names(1)
复制代码
这种方式中,批处理是变量名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
- REM 遍历2到3的数值
- for /l %%n in (2,1,3) do (
- REM 每次都要循环判断
- set /a i=0
- for %%a in (%names%) do (
- set /a i+=1
- if !i! EQU %%n echo 第%%n个人是%%a
- )
- )
- pause>nul
复制代码
之所以会这样麻烦,是由于在批处理中我们不能直接使用那个set(集合,names)参数,而在VBS中我们已经知道可以根据下标取它里面的某个值,因此就要简单很多了:
- names = array("张三", "李四", "王二麻子")
- for each a in names
- wscript.echo a
- next
- ' 第二到三个人,即下标 1 到 2 的,
- ' 如果 step 步长是 1,可以省略为
- ' for <variable> = <start> to <end>
- for n = 1 to 2 step 1
- a = names(n)
- ' 显示的是第几个人,因此是下标值加 1
- wscript.echo "第" & (n+1) & "个人是" & a
- next
复制代码
还有一对与数组相关的可能要经常使用到的函数是 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
- next
复制代码
还有一种叫做集合的东西,其实也很好理解,集合嘛,就是一堆东西放在一起,那他跟一组东西有什么区别呢?一组是有序号的,一堆没有序号,仅此而已。所以如果要把 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
- next
复制代码
|