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

[原创] WINDOWS中的脚本教程(No.04)

WINDOWS中的脚本 No.04

仔细考虑了一下,觉得之前的有些东西有必要着重地讲一下,那就是循环语句,以及经常使用的一些包装数据的东西,数组和集合。
    数组,顾名思义,就是装一组数值的东西,你可以认为你家的冰柜F是一个大小为3的数组,最顶上的一格F(0)装的是蔬菜,是冷藏室,中间一层F(1)装的是冰棍,是冷冻室,最下面一格F(2)是掏炉灰的。这里可以看出如果变量F代表一个数组,那么它里面装的东西是有顺序的,我们把代表每个东西的顺序的序号叫做“下标”,下标是从 0 开始的,因此总是比通常说的“第几个”的几要小 1 ,数组变量后面跟对小括号里面是一个数字,这就代表数组中的某一个特定的数值,比如 F(0) 代表 F 的第一个东西,F(2) 代表第三个东西,F(3)是错误的,因为没有第四个。一种初始化一个数组的方法是利用Array函数直接赋值,比如冰柜
  1. F = Array("冷藏室", "冷冻室", "炉灰坑")
复制代码

    大家知道批处理里面的FOR循环语句有种语法是
[quoto]FOR %variable IN (set) DO command [command-parameters][/quoto]
这里的 set 就和数组的意思大概是一样的,当然了,不要因为他叫“数”组就认为里面的东西不一定全是数字,可以是任何类型的数据,比如字符,日期,甚至是任意的对象,显然叫“字符串组”、“日期组”甚至“东西组”是没有必要的,于是就沿用数组这个名字了。
    VBS中比批处理便利的就是什么东西都能存到变量里,并且是个东西都会有然后想用的时候直接调变量。我们来看个例子,有三个人依次是张三李四王二麻子,现在要编一段代码分别显示他们的名字,然后指明第二个人是谁。
我们可能会写出如下的批处理代码:
  1. @echo off
  2. set names=张三 李四 王二麻子
  3. for %%a in (%names%) do echo %%a
  4. setlocal enabledelayedexpansion
  5. set /a i=0
  6. for %%a in (%names%) do (
  7.   set /a i+=1
  8.   if !i! EQU 2 echo 第二个人是%%a
  9. )
  10. pause>nul
复制代码

与批处理的 for ... in () 相对应,在VBS中用 for each ... in 的格式可以遍历一个数组或者集合,代码如下:
  1. names = array("张三", "李四", "王二麻子")
  2. for each a in names
  3.   wscript.echo a
  4. next
  5. a = names(1)  '第二个人的下标为 1
  6. wscript.echo "第二个人是" & a
复制代码

从这里可以看出,利用数组可以更加方便和准确地操作数据。
或许有人想到,for 有 /f 参数,直接用字符分隔的方式不就能获取第二个吗?
  1. @echo off
  2. set nameStr="张三 李四 王二麻子"
  3. for /f "tokens=1,2,3 delims= " %%a in (%nameStr%) do echo 第二个人是%%b
  4. pause>nul
复制代码

相对于批处理中这种用分隔字符分割一个字符串,得到几段字符串的办法,VBS中也有这种功能的函数Split,这是一个非常有用的函数,在我日常的实用中,数组一般都是用它创造出来的,因为他的返回值就是一个数组,代码如下
  1. nameStr = "张三 李四 王二麻子"
  2. ' 指明分割字符串 nameStr,分隔字符(或者叫界定)是空格 " ",
  3. ' 并将返回的数组存放到变量 names 中
  4. names = Split(nameStr, " ")
  5. ' 稍微一想,分割出来的数组中的第二段就是我们要的
  6. 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>。
我们把之前的问题稍微改一改,最后不是“第二个人”,而是“第二到三个人”,那么又改怎么编码呢?如果用批处理我们可能需要再套一层循环,每次都判断是第几个:
  1. @echo off
  2. set names=张三 李四 王二麻子
  3. for %%a in (%names%) do echo %%a
  4. setlocal enabledelayedexpansion
  5. REM 遍历2到3的数值
  6. for /l %%n in (2,1,3) do (
  7.   REM 每次都要循环判断
  8.   set /a i=0
  9.   for %%a in (%names%) do (
  10.     set /a i+=1
  11.     if !i! EQU %%n echo 第%%n个人是%%a
  12.   )
  13. )
  14. pause>nul
复制代码

之所以会这样麻烦,是由于在批处理中我们不能直接使用那个set(集合,names)参数,而在VBS中我们已经知道可以根据下标取它里面的某个值,因此就要简单很多了:
  1. names = array("张三", "李四", "王二麻子")
  2. for each a in names
  3.   wscript.echo a
  4. next
  5. ' 第二到三个人,即下标 1 到 2 的,
  6. ' 如果 step 步长是 1,可以省略为
  7. ' for <variable> = <start> to <end>
  8. for n = 1 to 2 step 1
  9.   a = names(n)
  10.   ' 显示的是第几个人,因此是下标值加 1
  11.   wscript.echo "第" & (n+1) & "个人是" & a
  12. next
复制代码

还有一对与数组相关的可能要经常使用到的函数是 UBound 和 LBound,分别是取一个数组下标的最大值和最小值,以我们的冰柜为例,UBound(F) 的值是 2,LBound(F) 的值是 0 ,于是如果来个新要求,“在不知道总共有多少人的情况下,列出所有人的名字并指出他们分别是第几个”,我们可以写出如下代码:
  1. names = array("武大", "张三", "李四", "王二麻子")
  2. s = lbound(names)
  3. e = ubound(names)
  4. for n = s to e
  5.   a = names(n)
  6.   wscript.echo "第" & (n+1) & "个人是" & a
  7. next
复制代码

还有一种叫做集合的东西,其实也很好理解,集合嘛,就是一堆东西放在一起,那他跟一组东西有什么区别呢?一组是有序号的,一堆没有序号,仅此而已。所以如果要把 for 循环用在集合上,那么就只能用 for each ... in 的方式了,这个跟数组差不多,就先不讲了。

我们来看个数组应用的例子吧,有些在批处理中很难处理的问题,在VBS中由于设计的不同,就很容易解决了。
批处理中delims该怎样使用多个字符为分隔符?
http://www.bathome.net/viewthread.php?tid=7596
我之前以为批处理中能行,但是经人举例,发现错了,但是在VBS脚本中决绝非常容易。就用我们之前的 Split 函数。
比如要用 ab 作为分隔符分割字符串 aabbabaabbceabd
  1. str = "aabbabaabbceabd"
  2. delims = "ab"
  3. arr = split(str, delims)
  4. s = lbound(arr)
  5. e = ubound(arr)
  6. wscript.echo "总共分割成了" & (e+1) & "段。"
  7. for n = s to e
  8.   a = arr(n)
  9.   wscript.echo "第" & (n+1) & "段是" & a
  10. next
复制代码

终于找到分割字串的函数了。。。

TOP

原帖由 s700800900 于 2010-6-22 16:01 发表
终于找到分割字串的函数了。。。

你应该去找个教程详细看看基本的东西。。。。

TOP

返回列表