`
iihero
  • 浏览: 258418 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

How to use "for/" batch command in Dos extention

 
阅读更多
以前常觉得DOS的 命令行功能太弱,无法象UNIX一样可以用命令行完成非常复杂的操作。实际上,当MS从WIN2K开始将命令行增强后,已经借鉴了相当多UNIX的优点, 虽然还无法做到象UNIX那么灵活,但已可完成绝大多数的任务,比如用&&和||连接两个(或更多)命令,由前一个的返回值来决定下一个 是否执行,等等。而在这些增强中,最明显的,就是FOR命令。

举个例子,用适当的参数,可用FOR命令将 date /t 的输出 从 "Sat 07/13/2002" 变成你想要的格式,比如, "2002-07-13":

c:>for /f "tokens=2,3,4 delims=/ " %a in ('date /t') do @echo %c-%a-%b      2002-07-13

该例将在(3)中详细说明。

0. 基本应用

简单说,FOR是个循环,可以用你指定的循环范围生成一系列命令。最简单的例子,就是人工指定循环范围,然后对每个值执行指定的命令。例如,想快速报告每个硬盘分区的剩余空间:

      for %a in (c: d: e: f:) do @dir %a|find "可用字节"

将输出:

                     8 Dir(s)       1,361,334,272 bytes free
                    15 Dir(s)       8,505,581,568 bytes free
                    12 Dir(s)      12,975,149,056 bytes free
                     7 Dir(s)      11,658,854,400 bytes free

用它可以使一些不支持通配符的命令对一系列文件进行操作。在WIN9X中,TYPE命令(显示文件内容)是不支持*.txt这种格式的(WIN2K开始TYPE已支持通配)。遇到类似情况就可以用FOR:

      for %a in (*.txt) do type %a

这些还不是FOR最强大的功能。我认为它最强大的功能,表现在以下这些高级应用:

1. 可以用 /r 参数遍历整个目录树
2. 可以用 /f 参数将文本文件内容作为循环范围
3. 可以用 /f 参数将某一命令执行结果作为循环范围
4. 可以用 %~ 操作符将文件名分离成文件名、扩展名、盘符等独立部分


现分别举例说明如下:

1. 用 /r 遍历目录树

当用 *.* 或 *.txt 等文件名通配符作为 for /r 的循环范围时,可以对当前目录下所有文件(包括子目录里面的文件)进行操作。举个例子,你想在当前目录的所有txt文件(包括子目录)内容中查找"bluebear"字样,但由于find本身不能遍历子目录,所以我们用for:

      for /r . %a in (*.txt) do @find "bluebear" %a

find 前面的 @ 只是让输出结果不包括 find 命令本身。这是DOS很早就有的功能。和FOR无关。

当用 . 作为循环范围时,for 只将子目录的结构(目录名)作为循环范围,而不包括里面的文件。有点象 TREE 命令,不过侧重点不同。TREE 的重点是用很漂亮易读的格式输出,而FOR的输出适合一些自动任务,例如,我们都知道用CVS管理的项目中,每个子目录下都会有一个CVS目录,有时在软件发行时我们想把这些CVS目录全部去掉:

      for /r . %a in (.) do @if exist %aCVS rd /s /q %aCVS

先用 if exist 判断一下,是因为 for 只是机械的对每个目录进行列举,如果有些目录下面没有CVS也会被执行到。用 if exist 判断一下比较安全。

这种删除命令威力太大,请小心使用。最好是在真正执行以上的删除命令前,将 rd /s /q 换成 @echo 先列出要删出的目录,确认无误后再换回rd /s /q:

      for /r . %a in (.) do @if exist %aCVS @echo %aCVS

可能目录中会多出一层 ".",比如 c:projrelease.CVS ,但不会影响命令的执行效果。

2. 将某一文件内容或命令执行结果作为循环范围:

假如你有一个文件 todel.txt,里面是所有要删除的文件列表,现在你想将里面列出的每个文件都删掉。假设这个文件是每个文件名占一行,象这样:

      c:tempa1.txt      c:tempa2.txt      c:tempsubdirb3.txt      c:tempsubdirb4.txt

那么可以用FOR来完成:

      for /f %a in (todel.txt) do del %a

这个命令还可以更强大。比如你的 todel.txt 并不是象上面例子那么干净,而是由DIR直接生成,有一些没用的信息,比如这样:

       Volume in drive D is DATA
       Volume Serial Number is C47C-9908

         Directory of D:tmp

        09/26/2001      12:50 PM                18,426 alg0925.txt
        12/02/2001      04:29 AM                   795 bsample.txt
        04/11/2002      04:18 AM                 2,043 invitation.txt
                     4 File(s)             25,651 bytes
                     0 Dir(s)       4,060,700,672 bytes free

for 仍然可以解出其中的文件名并进行操作:

      for /f "skip=5 tokens=5" %a in (todel.txt) do @if exist %a DEL %a

当然,上面这个命令是在进行删除,如果你只是想看看哪些文件将被操作,把DEL换成echo:

      for /f "skip=5 tokens=5" %a in (todel.txt) do @if exist %a echo %a

你将看到:

      alg0925.txt
      bsample.txt
      invitation.txt

skip =5表示跳过前5行(就是DIR输出的头部信息),tokens=5表示将每行的第5列作为循环值放入%a,正好是文件名。在这里我加了一个文件存在判 断,是因为最后一行的"free"刚好也是第5列,目前还想不出好的办法来滤掉最后两行,所以检查一下可保万无一失。

3. 可以用 /f 参数将某一命令执行结果作为循环范围

非常有用的功能。比如,我们想知道目前的环境变量有哪些名字(我们只要名字,不要值)。可是SET命令的输出是"名字=值"的格式,现在可以用FOR来只取得名字部分:

      FOR /F "delims==" %i IN ('set') DO @echo %i

将看到:

      ALLUSERSPROFILE
      APPDATA
      CLASSPATH
      CommonProgramFiles
      COMPUTERNAME
      ComSpec
      dircmd
      HOMEDRIVE      ......

这里是将set命令执行的结果拿来作为循环范围。delims==表示用=作为分隔符,由于FOR /F默认是用每行第一个TOKEN,所以可以分离出变量名。如果是想仅列出值:

      FOR /F "delims== tokens=2" %i IN ('set') DO @echo %i

tokens=2和前例相同,表示将第二列(由=作为分隔符)作为循环值。

再来个更有用的例子:

我们知道 date /t (/t表示不要询问用户输入)的输出是象这样的:

      Sat 07/13/2002

现在我想分离出日期部分,也就是13:

      for /f "tokens=3 delims=/ " %a in ('date /t') do @echo %a

实际上把 tokens后面换成1,2,3或4,你将分别得到Sat, 07, 13和2002。注意delims=/后面还有个空格,表示/和空格都是分隔符。由于这个空格delims必须是/f选项的最后一项。

再灵活一点,象本文开头提到的,将日期用2002-07-13的格式输出:

      for /f "tokens=2,3,4 delims=/ " %a in ('date /t') do @echo %c-%a-%b

当tokens后跟多个值时,将分别映射到%a, %b, %c等。实际上跟你指定的变量有关,如果你指定的是 %i, 它们就会用%i, %j, %k等。

灵活应用这一点,几乎没有做不了的事。

4. 可以用 %~ 操作符将文件名分离成文件名、扩展名、盘符等独立部分

这个比较简单,就是说将循环变量的值自动分离成只要文件名,只要扩展名,或只要盘符等等。

例:要将 c:mp3下所有mp3的歌名列出,如果用一般的 dir /b/s 或 for /r ,将会是这样:

      g:mp3Archived5-18-01-A游鸿明-下沙游鸿明-01 下沙.mp3
      g:mp3Archived5-18-01-A游鸿明-下沙游鸿明-02 21个人.mp3
      ......
      g:mp3Archived5-18-01-A王菲-寓言王菲-阿修罗.mp3
      g:mp3Archived5-18-01-A王菲-寓言王菲-彼岸花.mp3
      g:mp3Archived5-18-01-A王菲-寓言王菲-不爱我的我不爱.mp3
      ......

如果我只要歌名(不要路径和".mp3"):

      游鸿明-01 下沙
      游鸿明-02 21个人
      ......
      王菲-阿修罗
      王菲-彼岸花
      王菲-不爱我的我不爱
      ......

那么可以用FOR命令:

      for /r g:mp3 %a in (*.mp3) do @echo %~na

凡是 %~ 开头的操作符,都是文件名的分离操作。具体请看 for /? 帮助。

本文举的例子有些可能没有实际用处,或可用其它办法完成。仅用于体现FOR可以不借助其它工具,仅用DOS命令组合,就可完成相当灵活的任务。

具体请看 for /? 帮助

For命令具体解释

FOR %variable IN (set) DO command [command-parameters]

      %variable 指定一个单一字母可替换的参数。
      (set) 指定一个或一组文件。可以使用通配符。
      command 指定对每个文件执行的命令。
      command-parameters
                 为特定命令指定参数或命令行开关。

在批处理文件中使用 FOR 命令时,指定变量请使用 %%variable 而不要用 %variable。变量名称是区分大小写的,所以 %i 不同于 %I.

如果命令扩展名被启用,下列额外的 FOR 命令格式会受到支持:

FOR /D %variable IN (set) DO command [command-parameters]

如果集中包含通配符,则指定与目录名匹配,而不与文件名匹配。

FOR /R [[drive:]path] %variable IN (set) DO command [command-parameters]

检查以 [drive:]path 为根的目录树,指向每个目录中的FOR 语句。如果在 /R 后没有指定目录,则使用当前目录。如果集仅为一个单点(.)字符,则枚举该目录树。

FOR /L %variable IN (start,step,end) DO command [command-parameters]

该集表示以增量形式从开始到结束的一个数字序列。因此,(1,1,5) 将产生序列 1 2 3 4 5,(5,-1,1) 将产生序列 (5 4 3 2 1)。

FOR /F ["options"] %variable IN (file-set) DO command [command-parameters]
FOR /F ["options"] %variable IN ("string") DO command [command-parameters]
FOR /F ["options"] %variable IN ('command') DO command [command-parameters]

或者,如果有 usebackq 选项:

FOR /F ["options"] %variable IN (file-set) DO command [command-parameters]
FOR /F ["options"] %variable IN ("string") DO command [command-parameters]
FOR /F ["options"] %variable IN ('command') DO command [command-parameters]

filenameset 为一个或多个文件名。继续到 filenameset 中的下一个文件之前,每份文件都已被打开、读取并经过处理。处理包括读取文件,将其分成一行行的文字,然后将每行解析成零或更多的符号。然后用已找到的符号字符串变量值调用 For 循环。以默认方式,/F 通过每个文件的每一行中分开的第一个空白符号。跳过空白行。您可通过指定可选 "options" 参数替代默认解析操作。这个带引号的字符串包括一个或多个指定不同解析选项的关键字。这些关键字为:

            eol=c - 指一个行注释字符的结尾(就一个)
            skip=n - 指在文件开始时忽略的行数。
            delims=xxx - 指分隔符集。这个替换了空格和跳格键的
                              默认分隔符集。
            tokens=x,y,m-n - 指每行的哪一个符号被传递到每个迭代
                              的 for 本身。这会导致额外变量名称的分配。m-n
                              格式为一个范围。通过 nth 符号指定 mth。如果
                              符号字符串中的最后一个字符星号,
                              那么额外的变量将在最后一个符号解析之后
                              分配并接受行的保留文本。
            usebackq - 指定新语法已在下类情况中使用:
                              在作为命令执行一个后引号的字符串并且一个单
                              引号字符为文字字符串命令并允许在 filenameset
                              中使用双引号扩起文件名称。

某些范例可能有助:

FOR /F "eol=; tokens=2,3* delims=, " %i in (myfile.txt) do @echo %i %j %k

会分析 myfile.txt 中的每一行,忽略以分号打头的那些行,将每行中的第二个和第三个符号传递给 for 程序体;用逗号和/或空格定界符号。请注意,这个 for 程序体的语句引用 %i 来取得第二个符号,引用 %j 来取得第三个符号,引用 %k 来取得第三个符号后的所有剩余符号。对于带有空格的文件名,您需要用双引号将文件名括起来。为了用这种方式来使用双引号,您还需要使用 usebackq 选项,否则,双引号会被理解成是用作定义某个要分析的字符串的。

%i 专门在 for 语句中得到说明,%j 和 %k 是通过 tokens= 选项专门得到说明的。您可以通过 tokens= 一行指定最多 26 个符号,只要不试图说明一个高于字母 'z' 或 'Z' 的变量。请记住,FOR 变量是单一字母、分大小写和全局的;而且,同时不能有 52 个以上都在使用中。

您还可以在相邻字符串上使用 FOR /F 分析逻辑;方法是,用单引号将括号之间的 filenameset 括起来。这样,该字符串会被当作一个文件中的一个单一输入行。

最后,您可以用 FOR /F 命令来分析命令的输出。方法是,将括号之间的 filenameset 变成一个反括字符串。该字符串会被当作命令行,传递到一个子 CMD.EXE,其输出会被抓进内存,并被当作文件分析。因此,以下例子:

          FOR /F "usebackq delims==" %i IN (`set`) DO @echo %i

会枚举当前环境中的环境变量名称。

另外,FOR 变量参照的替换已被增强。您现在可以使用下列选项语法:

         ~I - 删除任何引号("),扩充 %I
         %~fI - 将 %I 扩充到一个完全合格的路径名
         %~dI - 仅将 %I 扩充到一个驱动器号
         %~pI - 仅将 %I 扩充到一个路径
         %~nI - 仅将 %I 扩充到一个文件名
         %~xI - 仅将 %I 扩充到一个文件扩展名
         %~sI - 扩充的路径只含有短名
         %~aI - 将 %I 扩充到文件的文件属性
         %~tI - 将 %I 扩充到文件的日期/时间
         %~zI - 将 %I 扩充到文件的大小
         %~$PATH:I - 查找列在路径环境变量的目录,并将 %I 扩充
                       到找到的第一个完全合格的名称。如果环境变量名
                       未被定义,或者没有找到文件,此组合键会扩充到
                       空字符串

可以组合修饰符来得到多重结果:

         %~dpI - 仅将 %I 扩充到一个驱动器号和路径
         %~nxI - 仅将 %I 扩充到一个文件名和扩展名
         %~fsI - 仅将 %I 扩充到一个带有短名的完整路径名
         %~dp$PATH:i - 查找列在路径环境变量的目录,并将 %I 扩充
                       到找到的第一个驱动器号和路径。
         %~ftzaI - 将 %I 扩充到类似输出线路的 DIR

在以上例子中,%I 和 PATH 可用其他有效数值代替。%~ 语法用一个有效的 FOR 变量名终止。选取类似 %I 的大写变量名比较易读,而且避免与不分大小写的组合键混合。
0
0
分享到:
评论

相关推荐

    The Definitive Guide to Spring Batch, 2nd Edition.epub

    Finally this book demonstrates how you can use areas of the Spring portfolio beyond just Spring Batch 4 to collaboratively develop mission-critical batch processes. You’ll see how a new class of use...

    批处理for的用法(详细)

    FOR /D %%I IN (Command1) DO Command2 ``` 这个开关只搜索指定的目录,不包括子目录。例如: ```batch @echo off for /d %%i in (c:\*) do echo %%i pause >nul ``` 这段代码将显示C盘根目录下的所有...

    MS Dos Batch Command

    MS Dos Batch Command是一种在DOS环境下执行的一系列命令集合,用于自动化执行重复性的任务。本文主要介绍了批处理内部的一些常用命令。 1. Echo命令:Echo命令用于开启或关闭命令提示符的回显功能,或者显示指定的...

    spring batch in action

    DESCRIPTION Even though running batch processes is an everyday task in almost all IT departments, Java developers have had few options for writing batch applications. The result? No standards, poor ...

    Advanced BAT to EXE Converter2.83老朽痴拙汉化版(BAT编辑转换器)

    -MouseCMD allows you to use Mouse Input for your batch files -BrowseFiles allows you to use Windows Common Dialog box to browse for a file -BrowseFolder allows you to use a Windows Dialog to browse ...

    MS-DOS 5.0

    below, you must add the specified /machine switch to the DEVICE=HIMEM.SYS command in your CONFIG.SYS file before you run Setup. After changing the CONFIG.SYS file, run Setup. System Switch ------ ...

    Files Batch Command - 多文件改名

    ★Files Batch Command 在资源管理器中选择文件(可多选),执行右键菜单的 Files Batch Command 项,在弹出 菜单中可完成 改名,修改时间等功能。 使用: 拷到硬盘上,执行reg.bat即可。 删除时执行unReg....

    pro spring batch

    What you'll learn * Batch concepts and how they relate to the Spring Batch framework * How to use declarative I/O using the Spring Batch readers/writers * Data integrity techniques used by Spring ...

    DOS批处理 FOR 高级用法.txt

    在深入探讨"DOS批处理FOR高级用法"之前,我们首先需要理解DOS批处理脚本的基本概念。批处理脚本是一种在DOS环境下运行的自动化脚本,它由一系列命令组成,这些命令通常用于执行复杂的任务,如文件管理、系统配置等。...

    史上最强之dos命令 - FOR - 高级应用范例

    FOR [选项] %variable IN (集合) DO command [command-parameters] ``` 其中: - **选项**:控制循环的行为,如文件名模式匹配、跳过某些行等。 - **%variable**:代表循环中的每个元素。 - **(集合)**:定义循环的...

    Spring Batch in Action英文pdf版

    Spring Batch in Action是一本专注于Spring Batch框架的书籍,由Arnaud Cogoluègnes、Thierry Templier、Gary Gregory和Olivier Bazoud合著,由Manning Publications公司出版。这本书详细介绍了如何使用Spring ...

    Introduction to MATLAB for Engineers

    - **4.7–1 Using the Switch Structure for Calendar Calculations**: This example illustrates the use of switch statements in MATLAB for calendar calculations, which can be applied in various ...

    DOSCommand-102Tokyo_cheese9ca_DOSCommand-102Tokyo_DOSCommand_mem

    DOSCommand-102TokyoTurboPack DOSCommand component let you execute a dos program (exe com or batch file) and catchthe ouput in order to put it in a memo or in a listbox ...You can also send inputs.The ...

    DOS-BATCH-练习参考用

    【DOS/BATCH 知识点详解】 DOS(Disk Operating System)是早期个人计算机上广泛使用的操作系统之一,而批处理(Batch)是DOS系统中的一个重要特性,它允许用户编写一系列命令,形成一个批处理文件,从而实现自动化...

    sttic library to get the result of batch command

    "sttic library to get the result of batch command" 是一个针对VC++开发的静态库,它的主要功能是在同步模式下获取批量命令执行的结果。这个库对于需要在C++程序中调用批处理脚本并获取其运行结果的应用场景非常...

    批处理For语句从入门到精通(完整版)

    for /f [options] %%I in (file) do command [command-parameters] ``` `options` 包括一系列选项,如`delims=`、`tokens=`、`skip=`、`eol=`等,用于定制解析过程。 ##### (二)切分字符串的利器:delims= `...

    DOS命令大全(include all dos command)

    - 语法:`FOR variable in (set) DO command` - 示例:`FOR %%I IN (*.txt) DO ECHO Processing %%I` 4. **GOTO**:跳转到批处理文件中的标签。 - 语法:`GOTO label` - 示例:`GOTO :START` 5. **CALL**:调用...

    batch command generator

    华为公司开发的这款"batch command generator"很可能是为了简化IT管理员的日常任务,特别是对于需要频繁执行相同或类似命令序列的情况。 批处理脚本的基本结构包括命令、指令和可选的参数。以下是一些关键的批处理...

Global site tag (gtag.js) - Google Analytics