精华内容
下载资源
问答
  • //判断文件存在 @echo off if exist "d:\dd.txt" ( del "d:\dd.txt" echo 文件已被删除 )else ( echo 您要删除的文件不存在 ) pause
  • 批处理判断文件夹是否存在

    千次阅读 2016-11-17 21:25:08
    批处理判断文件夹是否存在本文转载自:批处理判断文件夹是否存在 - Virus-BeautyCode - 博客园先看一段bat命令@echo off @title 批处理判断文件夹是否存在if exist folder1 ( echo "已经存在文件夹" ) else ( md ...

    批处理判断文件夹是否存在

    本文转载自:批处理判断文件夹是否存在 - Virus-BeautyCode - 博客园

    先看一段bat命令

    @echo off
    @title 批处理判断文件夹是否存在
    
    if exist folder1 (
       echo "已经存在文件夹"
    ) else (
    md folder1
    )
    
    if not exist folder2 md folder2
    
    pause

    命令中首先判断当前目录中是否存在folder1,如果存在,打印“已经存在文件夹”;如果不存在就用md命令建立文件夹。

    1. for in 结构:

    下面这个语句可以把当前文件夹所有子文件夹下的txt文件合并成一个文件

    for /D %%d in (*) do type %%d\*.txt >>result.txt

    有时候程序输出的txt文件最后一行缺少回车符号,如果两个文件直接用type重定向合并,会导致错误,所以可以做一个空行文件oneline.txt,然后改成这种:

    for /D %%d in (*) do type %%d\*.txt oneline.txt >>result.txt

    2. 取日期和时间。

    批处理环境里可以使用%date%变量和%time%变量,不同的机器这个变量的格式也不同,
    可以试试echo %date% %time%看格式

    然后使用:~begin,len的方式取的变量的字串类似函数substr($str, $begin, $len),例如:

    echo %date%

    结果输出:

    2006-06-20 星期二

    那么取从0开始的索引0,字串长度为10,即:

    echo %date:~0,10%

    结果输出:

    2006-06-20

    例如我想合并今天的日志文件,可以这样:

    set myval=%date:~0,10%
    for /D %%d in (*) do type %%d\%myval%.log >>result.txt 

    不同机器使用cmd拷贝文件,思路是,先建立链接,然后映射网络驱动器,然后就可以拷贝了

    net use z: \\192.168.2.112\C$ "wyzwyw" /USER:Administrator 
    copy 1.txt z: 
    
    copy z:\boot.ini c:\boot.txt 
    net use z: /delete
    展开全文
  • 批处理for语句

    2014-08-20 13:48:54
    批处理是一门简单的脚本语言,虽然不能... 2、命令少,语句简洁,上手非常快;  3、编写出来的脚本小巧玲珑,随写随用;  但是,因为它以命令行方式工作,操作多有不便,在图形界面大行其道的windows世界里,
    批处理是一门简单的脚本语言,虽然不能独当一面,但是,若作为工作中的辅助工具,绝对会让大家有随用随写、称心如意的畅快感。

      和其他语言相比,批处理语言有其先天性的优势:

      1、系统自带,无需另行安装;
      2、命令少,语句简洁,上手非常快;
      3、编写出来的脚本小巧玲珑,随写随用;

      但是,因为它以命令行方式工作,操作多有不便,在图形界面大行其道的windows世界里,多多少少会让大众望而却步;就算是对命令行有好感的新手,面对微软有如天书的帮助文件,很多人也会败下阵来,因此,论坛里很多会员也发出了编写系统的批处理教程的呼声。

      编写系统的批处理新手教程,一直是论坛管理层讨论的热点问题,但是,各位管理人员大多都有工作在身,而系统的教程涉及的面是如此之广,面对如此浩大的工程,仅凭一两个人的力量,是难以做好的,因此,本人退而求其次,此次发布的教程,以专题的形式编写,日后人手渐多之后,再考虑组织人力编写全面的教程。

      之所以选择最难的for,一是觉得for最为强大,是大多数人最希望掌握的;二是若写其他命令教程,如果没有for的基础,展开来讲解会无从下手;三是for也是批处理中最复杂最难掌握的语句,把它攻克了,批处理的学习将会一片坦途。

      这次的for语句系列教程,打算按照for语句的5种句式逐一展开,在讲解 for /f 的时候,会穿插讲解批处理中一个最为关键、也是新手最容易犯错的概念:变量延迟,大纲如下: 

    引用:


    一 前言
    二 for语句的基本用法
    三 for /f (含变量延迟)
    四 for /r
    五 for /d
    六 for /l

    一、前言

      在批处理中,for是最为强大的命令语句,它的出现,使得解析文本内容、遍历文件路径、数值递增/递减等操作成为可能;配合if、call、goto等流程控制语句,更是可以实现脚本复杂的自动化、智能化操作;合理使用for语句,还能使代码大为简化,免除各位编写大量重复语句之苦。而能否熟练使用for语句,已经成为衡量一个人批处理水平高低最主要的标准。

      在这个系列教程中,我将通过实际应用中频繁出现的例子,带领大家步入for语句的神奇之门,一步步迈向for语句的魔幻殿堂,使得大家在实际的应用中,能独立写出简洁高效的代码,在批处理的世界里自由驰骋。

      注意:以下的讲解,都是基于简体中文版Windows XP Pro SP3的操作系统环境。

    二、for语句的基本用法[2008.11.9更新]

      正如色彩缤纷的七彩光芒是由红绿蓝三原色构成的一样,最复杂的for语句,也有其基本形态,它的模样是这样的:
      在cmd窗口中: 

    复制内容到剪贴板 

    代码:

    for %I in (command1) do command2

      在批处理文件中: 

    复制内容到剪贴板 

    代码:

    for %%I in (command1) do command2

      之所以要区分cmd窗口和批处理文件两种环境,是因为在这两种环境下,命令语句表现出来的行为虽然基本一样,但是在细节上还是稍有不同,最明显的一个差异就是:在cmd窗口中,for之后的形式变量I必须使用单百分号引用,即%I;而在批处理文件中,引用形式变量I必须使用双百分号,即%%I。为了方便起见,若不是特别强调,以下的讲解都以批处理文件环境为例。

      我们先来看一下for语句的基本要素都有些什么: 

    引用:

      1、for、in和do是for语句的关键字,它们三个缺一不可;
      2、%%I是for语句中对形式变量的引用,就算它在do后的语句中没有参与语句的执行,也是必须出现的;
      3、in之后,do之前的括号不能省略;
      4、command1表示字符串或变量,command2表示字符串、变量或命令语句;

      现在,你可能已经会写一个简单的for语句了,比如:
    [code1] 

    复制内容到剪贴板 

    代码:

    @echo off
    for %%I in (bbs.bathome.net) do echo %%I
    pause

      保存为批处理文件并执行,将会在弹出的批处理窗口中看到这样的信息:
    [result1] 

    引用:

    bbs.bathome.net
    请按任意键继续...

      很快地,你会觉得这个for语句是如此的简单,简单到你丝毫感受不出它的强大:这个for语句,和我直接用echo语句没什么两样啊!

      是的,演示代码永远都只是演示而已,就像大多数高级语言的教科书一样,在引导新手学习的时候,基本上都是千篇一律地告诉大家如何编写一个能显示 hello world! 的窗口,从这些演示代码中,你看不到它们具有多少实用性,你只是感到有点好奇:咦,居然弹出了一个窗口?片刻之后,你就会觉得索然无味。

      那好吧,为了让大家对for更加感兴趣,我们先来分析一下for语句的一些注意事项,之后,再让大家看看更为强大的for语句实例。
       

    引用:

      1、for语句的形式变量I,可以换成26个字母中的任意一个,这些字母会区分大小写,也就是说,%%I和%%i会被认为不是同一个变量;形式变量I还可以换成其他的字符,但是,为了不与批处理中的%0~%9这10个形式变量发生冲突,请不要随意把%%I替换为%%0 ~%%9中的任意一个;
      2、in和do之间的command1表示的字符串或变量可以是一个,也可以是多个,每一个字符串或变量,我们称之为一个元素,每个元素之间,用空格键、跳格键、逗号、分号或等号分隔;
      3、for语句依次提取command1中的每一个元素,把它的值赋予形式变量I,带到do后的command2中参与命令的执行;并且每次只提取一个元素,然后执行一次do后的命令语句,而无论这个元素是否被带到command2中参与了command2的运行;当执行完一次do后的语句之后,再提取command1中的下一个元素,再执行一次command2,如此循环,直到command1中的所有元素都已经被提取完毕,该for语句才宣告执行结束;

      其中,第3点是最为关键的,它描述了for语句的执行过程,是for语句的精髓所在,大家一定要牢记这一条,才能深刻理解更为复杂的for流程。

      有了以上的基础,我们再来看一个例子,这个例子修改了[code1]的部分内容,结果将大不一样:
    [code2] 

    复制内容到剪贴板 

    代码:

    @echo off
    for %%I in (bbs,bathome,net) do echo %%I
    pause

      和[code1]的执行结果[result1]相比,[result2]发生了如下变化:

      1、显示结果分成了3行(不算最后一行中文提示);
      2、每一行都从逗号处被切分;

      如果把 bbs.bathome.net 这个字符串中的点号换为空格、跳格或等号,执行结果将和example2的执行结果别无二致。

      现在,我们来分析一下[code2]代码中for语句的执行过程:

      首先,for语句以逗号为分隔符,把 bbs,bathome.net 这个字符串切分成三个元素:bbs、bathome和cn,由此决定了do后的语句将会被执行3次;
      然后,第一次执行过程是这样的:先把 bbs 这个字符串作为形式变量I的值,带入do后的语句中加以执行,也就是执行 echo %%I 语句,此时的I值为bbs,因此,第一次执行的结果,将会在屏幕上显示bbs这个字符串;第二次执行和第一次执行的过程是一样的,只不过此时I的值已经被替换为command1中的第二个元素了,也就是 bathome 这个字符串;如此循环,当第三次echo执行完毕之后,整条for语句才算执行完毕,此时,将执行下一条语句,也就是pause命令。

      其实,这个例子只比上一个例子多了一点花样,有趣了那么一点点:一条for语句的执行结果居然被分成了3行!

      为了让大家见识一下for的真正威力,本人绞尽脑汁,翻帖无数,不得要领,万般无奈之下,只好亮出了尘封在箱底多年的一段代码:检测当前硬盘都有哪些分区^_^
    [code3] 

    复制内容到剪贴板 

    代码:

    @echo off
    set str=c d e f g h i j k l m n o p q r s t u v w x y z
    echo 当前硬盘的分区有:
    for %%i in (%str%) do if exist %%i: echo %%i:
    pause

      这段代码能检测硬盘都有哪些分区,包括U盘和移动硬盘的分区,但是,当光驱中有盘的时候,也会被列出来,这是本代码的一个缺憾,在以后的讲解中,我将向大家讲述如何消除这个瑕疵,敬请关注本系列的后续章节。

      高级应用:

      想知道当前目录下都有哪些文件吗?请用下面的代码: 

    复制内容到剪贴板 

    代码:

    @echo off
    for %%i in (*.*) do echo "%%i"
    pause

      想列出当前目录下所有的文本文件吗?请用下面的代码: 

    复制内容到剪贴板 

    代码:

    @echo off
    for %%i in (*.txt) do echo "%%i"
    pause

      想列出只用两个字符作为文件名的文本文件吗?请用下面的代码: 

    复制内容到剪贴板 

    代码:

    @echo off
    for %%i in (??.txt) do echo "%%i"
    pause

      题外话:

      1、列出当前目录下各种文件的方法,最简单的还是用dir命令,但是,从以上代码中,各位可以加深对for语句执行流程的理解(用到了通配符*和?);
      2、注意:以上代码不能列出含有隐藏或系统属性的文件;

      练习:用for语句建立test1.txt、test2.txt和test3.txt三个文本文件。

      更全面的练习请看这个帖子:for语句从入门到精通配套练习题

    三、文本解析显神威:for /f 用法详解[2009.2.10更新]

        前言

      for /f 是个十分强大的家伙。

      如果说,for语句是批处理中最强大的语句的话,那么,for /f 就是精华中的精华。

      for /f 的强大,和它拥有众多的开关密切相关。因为开关众多,所以用法复杂,本章将分成若干小节,为大家逐一介绍强大的 for /f 语句。

        (一) 为解析文本而生:for /f 的基本用法

      所有的对象,无论是文件、窗体、还是控件,在所有的非机器语言看来,无外乎都是形如"c:\test.txt"、"CWnd"之类的文本信息;而所有的对象,具体的如ini文件中的某条配置信息、注册表中的某个键值、数据库中的某条记录……都只有转化为具有一定格式的文本信息,方可被代码识别、操控。可以说,编程的很大一部分工作,都是在想方设法绞尽脑汁如何提取这些文本信息。

      而提取文本信息,则是for /f的拿手好戏:读取文件内容;提取某几行字符;截取某个字符片段;对提取到的内容再切分、打乱、杂糅……只要你所能想到的花样,for /f 都会想方设法帮你办到,因为,for /f 就是被设计成专门用于解析文本的。

      先来看个例子。

      假如有个文本文件test.txt,内容如下:
    [txt1] 

    引用:

    论坛的目标是:不求最大,但求最好,做最实用的批处理论坛。
    论坛地址:bbs.bathome.net。
    这里是:新手晋级的福地,高手论剑的天堂。

      那么,将如下代码保存为test.cmd,并放在test.txt同一目录下运行,将会在屏幕上原样显示test.txt的内容:
    [code4] 

    复制内容到剪贴板 

    代码:

    @echo off
    for /f %%i in (test.txt) do echo %%i
    pause

      这段代码,主要是让你树立这样一种观念:读取文本文件的内容,请使用 for /f 语句!

      进阶话题:for /f 语句是把整个test.txt一次性显示出来的?

      在这段代码中,虽然执行结果是把test.txt中的所有内容都显示出来了,貌似 for /f 语句是把整个test.txt一次性显示到屏幕上,实际上并非如此。

      无论for语句做何种变化,它的执行过程仍然遵循基本的for流程:依次处理每个元素,直到所有的元素都被处理为止。只不过在for /f语句中,这里的元素是指文件中的每一行,也就是说,for /f 语句是以行为单位处理文本文件的。这是一条极为重要的规则,在上一章中也强调过它的重要性,希望在接下来的学习过程中,你能时刻牢记这一原则,那么,很多问题将会迎刃而解。以下是验证这一说法的演示代码(在[code4]的基础上添加了&pause语句):
    [code5] 

    复制内容到剪贴板 

    代码:

    @echo off
    for /f %%i in (test.txt) do echo %%i&pause
    pause

        (二) 切分字符串的利器:delims=

      也许你对[code4]这段代码不屑一顾:不就是把test.txt的内容显示出来了么?好像用处不大啊。

      好吧,我们来玩个魔术。

      还是[txt1]这段文本,把[code4]改造一下:
    [code6]

    复制内容到剪贴板 

    代码:

    @echo off
    for /f "delims=" %%i in (test.txt) do echo %%i
    pause

      再次运行test.cmd,看到什么变化了吗?!
    [result2] 

    复制内容到剪贴板 

    代码:

    论坛的目标是:不求最大
    论坛地址:bbs.bathome.net
    这里是:新手晋级的福地
    请按任意键继续...

      结果,你惊奇地发现,每行第一个逗号之后的所有内容都不见了(如果有不存在逗号的行,则保留原样),也就说,你成功地提取到了每行第一个逗号之前的所有内容!

      试想一下,这段代码会有什么用呢?

      如果别人给了你一个软件清单,每行都是"英文软件名(逗号)中文软件名"的格式,而你却只想保留英文名的时候,这段代码将是多么有用啊!再假设,有这么一个IP文件,第一列是数字格式的IP地址,第二列是具体的空间地址,列与列之间用逗号分隔,而你想提取其中数字格式的IP,呵呵,我不说你也知道该怎么办了吧?

      要是文本内容不是以逗号分隔,而是以其他符号分隔,那么,把"delims=,"的逗号换成相应的符号就可以了。

      在这里,我们引入了一个新的开关:"delims=,",它的含义是:以逗号作为被处理的字符串的分隔符号。

      在批处理中,指定分隔符号的方法是:添加一个形如 "delims=符号列表" 的开关,这样,被处理的每行字符串都会被符号列表中罗列出来的符号切分开来。

      需要注意的是:如果没有指定"delims=符号列表"这个开关,那么,for /f 语句默认以空格键或跳格键作为分隔符号。请把[txt1]中不同位置上的标点符号改为空格或跳格,再运行[code4]试试。

      进阶话题:如果我要指定的符号不止一个,该怎么办?

      在上面的讲解中,我提到了指定分隔符号的方法:添加一个形如"delims=符号列表"的开关。不知道你注意到没有,我的说法是"符号列表"而非"符号",这是大有讲究的,因为,你可以一次性指定多个分隔符号!

      还是以[txt1]为例,把[code6]再改造一下:
    [code7] 

    复制内容到剪贴板 

    代码:

    @echo off
    for /f "delims=." %%i in (test.txt) do echo %%i
    pause

      结果显示:
    [result3] 

    复制内容到剪贴板 

    代码:

    论坛的目标是:不求最大
    论坛地址:bbs
    这里是:新手晋级的福地
    请按任意键继续...

      这样,第一个点号或第一个逗号之前的内容都被提取出来了。

      [code7]的执行过程是:逐行读取test.txt中的内容,以点号和逗号切分每一行的内容(不存在点号和逗号的行,则不再切分,为了描述的方便,我们把被点号或逗号切分的一个一个的字符串片段,称之为节),然后,for /f 会提取第一节的内容作为最终结果,显示在屏幕上。需要注意的是,在这里,所有行的字符串被切分成了两个以上的节,但是,[code7]的代码只会提取第一节字符串的内容,因为 for /f 语句默认只提取第一节的符串。


        (三) 定点提取:tokens=

      上一节在讲解 delims= 的时候,我一再强调 for /f 默认只能提取到第一节的内容,现在我们来思考一个问题:如果我要提取的内容不在第一节上,那怎么办?

      这回,就该轮到 tokens= 出马了。

      tokens= 后面一般跟的是数字,如 tokens=2,也可以跟多个,但是每个数字之间用逗号分隔,如 tokens=3,5,8,它们的含义分别是:提取第2节字符串、提取第3、第5和第8节字符串。注意,这里所说的“节”,是由 delims= 这一开关划分的,它的内容并不是一成不变的。

      下面来看一个例子:
    [txt2] 

    复制内容到剪贴板 

    代码:

    尺有所短,寸有所长,学好批处理没商量,考虑问题复杂化,解决问题简洁化。

      对[txt2]这段文本,假设它们保存在文件test.txt中,如果我想提取“学好批处理没商量”这句话,该如何写代码呢?

      我们稍微观察一下[txt2]就会发现,如果以逗号作为切分符号,就正好可以把“学好批处理没商量”化为单独的一“节”,结合上一节的讲解,我们知道,"delims=," 这个开关是不可缺少的,而要提取的内容在以逗号切分的第3节上,那么,tokens= 后面的数字就应该是3了,最终的代码如下:
    [code8] 

    复制内容到剪贴板 

    代码:

    @echo off
    for /f "delims=, tokens=3" %%i in (test.txt) do echo %%i
    pause

      如果我们现在要提取的不只一个“节”,而是多个,那又怎么办呢?比如,要提取以逗号切分的第2节和第5节字符串,是写成这样吗?
    [code9] 

    复制内容到剪贴板 

    代码:

    @echo off
    for /f "delims=, tokens=2,5" %%i in (test.txt) do echo %%i
    pause

      运行批处理后发现,执行结果只显示了第2节的内容。

      原来,echo 后面的 %%i 只接收到了 tokens=2,5 中第一个数值2所代表的那个字符串,而第二个数值5所代表的字符串因为没有变量来接收,所以就无法在执行结果中显示出来了。

      那么,要如何接收 tokens= 后面多个数值所指代的内容呢?

      for /f 语句对这种情况做如下规定:

      如果 tokens= 后面指定了多个数字,如果形式变量为%%i,那么,第一个数字指代的内容用第一个形式变量%%i来接收,第二个数字指代的内容用第二个形式变量%%j来接收,第三个数字指代的内容用第三个形式变量%%k来接收……第N个数字指代的内容用第N个形式变量来接收,其中,形式变量遵循字母的排序,第N个形式变量具体是什么符号,由第一个形式变量来决定:如果第一个形式变量是%%i,那么,第二个形式变量就是%%j;如果第一个形式变量用的是%%x,那么,第二个形式变量就是%%y。

      现在回头去看[code9],你应该知道如何修改才能满足题目的要求了吧?修改结果如下:
    [code10] 

    复制内容到剪贴板 

    代码:

    @echo off
    for /f "delims=, tokens=2,5" %%i in (test.txt) do echo %%i %%j
    pause

      如果有这样一个要求:显示[txt2]中的内容,但是逗号要替换成空格,如何编写代码?

      结合上面所学的内容,稍加思索,你可能很快就得出了答案:
    [code11] 

    复制内容到剪贴板 

    代码:

    @echo off
    for /f "delims=, tokens=1,2,3,4,5" %%i in (test.txt) do echo %%i %%j %%k %%l %%m
    pause

      写完之后,你可能意识到这样一个问题:假如要提取的“节”数不是5,而是10,或者20,或者更多,难道我也得从1写到10、20或者更多吗?有没有更简洁的写法呢?

      答案是有的,那就是:如果要提取的内容是连续的多“节”的话,那么,连续的数字可以只写最小值和最大值,中间用短横连接起来即可,比如 tokens=1,2,3,4,5 可以简写为 tokens=1-5 。

      还可以把这个表达式写得更复杂一点:tokens=1,2-5,tokens=1-3,4,5,tokens=1-4,5……怎么方便就怎么写吧。

      大家可能还看到一种比较怪异的写法:
    [code12] 

    复制内容到剪贴板 

    代码:

    @echo off
    for /f "delims=, tokens=1,*" %%i in (test.txt) do echo %%i %%j
    pause

      结果,第一个逗号不见了,取代它的是一个空格符号,其余部分保持不变。

      其中奥妙就在这个星号上面。

      tokens=后面所接的星号具备这样的功能:字符串从左往右被切分成紧跟在*之前的数值所表示的节数之后,字符串的其余部分保持不变,整体被*所表示的一个变量接收。

      理论讲解是比较枯燥的,特别是为了严密起见,还使用了很多限定性的修饰词,导致句子很长,增加了理解的难度,我们还是结合[code12]来讲解一下吧。

      [txt2] 的内容被切分,切分符号为逗号,当切分完第一节之后,切分动作不再继续下去,因为 tokens=1,* 中,星号前面紧跟的是数字1;第一节字符串被切分完之后,其余部分字符串不做任何切分,整体作为第二节字符串,这样,[txt2]就被切分成了两节,分别被变量%%i和变量%%j接收。

      以上几种切分方式可以结合在一起使用。不知道下面这段代码的含义你是否看得懂,如果看不懂的话,那就运行一下代码,然后反复揣摩,你一定会更加深刻地理解本节所讲解的内容的:
    [code13] 

    复制内容到剪贴板 

    代码:

    @echo off
    for /f "delims=, tokens=1,3-4,*" %%i in (test.txt) do echo %%i %%j %%k %%l
    pause

        (四) 跳过无关内容,直奔主题:skip=n

      很多时候,有用的信息并不是贯穿文本内容的始终,而是位于第N行之后的行内,为了提高文本处理的效率,或者不受多余信息的干扰,for /f 允许你跳过这些无用的行,直接从第N+1行开始处理,这个时候,就需要使用参数 skip=n,其中,n是一个正整数,表示要跳过的行数。例如:
    [code14] 

    复制内容到剪贴板 

    代码:

    @echo off
    for /f "skip=2" %%i in (test.txt) do echo %%i
    pause

      这段代码将跳过头两行内容,从第3行起显示test.txt中的信息。


        (五) 忽略以指定字符打头的行:eol=

      在cmd窗口中敲入:for /?,相关的解释为: 

    引用:

    eol=c           - 指一个行注释字符的结尾(就一个)

    引用:

    FOR /F "eol=; tokens=2,3* delims=, " %i in (myfile.txt) do @echo %i %j %k
        会分析 myfile.txt 中的每一行,忽略以分号打头的那些行……

      第一条解释狗屁不通,颇为费解:行注释字符的结尾是什么意思?“(就一个)”怎么回事?结合第二条解释,才知道eol有忽略指定行的功能。但是,这两条解释是互相矛盾的:到底是忽略以指定字符打头的行,还是忽略以指定字符结尾的行?

      实践是检验真理的唯一标准,还是用代码来检验一下eol的作用吧:
    [code15] 

    复制内容到剪贴板 

    代码:

    @echo off
    for /f "eol=;" %%i in (test.txt) do echo %%i
    pause

      结果,那些以分号打头的行没有显示出来。

      由此可见,第二条解释是正确的,eol= 的准确含义是:忽略以指定字符打头的行。而第一条的“结尾”纯属微软在信口开河。

      那么,“(就一个)”又作何解释呢?

      试试这个代码:
    [code16] 

    复制内容到剪贴板 

    代码:

    @echo off
    for /f "eol=,;" %%i in (test.txt) do echo %%i
    pause

      此时,屏幕上出现 此时不应有 ;"。 的报错信息。可见,在指定字符的时候,只能指定1个——在很多时候,我对这样的设计颇有微词而又无可奈何:为什么只能指定1个而不是多个?要忽略多个还得又是if又是findstr加管道来多次过滤,那效率实在太低下了——能用到的功能基本上都提供,但是却又做不到更好,批处理,你的功能为什么那么弱?

      不知道大家注意到没有,如果test.txt中有以分号打头的行,那么,这些行在代码[code14]的执行结果中将凭空消失。

      原来,for /f 语句是默认忽略以分号打头的行内容的,正如它默认以空格键或跳格键作为字符串的切分字符一样。

      很多时候,我们可以充分利用这个特点,比如,在设计即将用for读取的配置文件的时候,可以在注释文字的行首加上分号,例如在编写病毒文件查杀代码的时候,可以通过for语句来读取病毒文件列表,那么,病毒文件列表.ini这个配置文件可以这样写: 

    引用:

    ;以下是常见的病毒文件,请见一个杀一个^_^
    ;copyleft:没有
    qq.exe
    msn.exe
    iexplore.exe

      如果要取消这个默认设置,可选择的办法是:

      1、为eol=指定另外一个字符;
      2、使用 for /f "eol=" 语句,也就是说,强制指定字符为空,就像对付delims=一样。


        (六)如何决定该使用 for /f 的哪种句式?(兼谈usebackq的使用)

      for /f %%i in (……) do (……) 语句有好几种变形语句,不同之处在于第一个括号里的内容:有的是用单引号括起来,有的是用双引号包住,有的不用任何符号包裹,具体格式为: 

    引用:

      1、for /f %%i in (文件名) do (……)
      2、for /f %%i in ('命令语句') do (……)
      3、for /f %%i in ("字符串") do (……)

      看到这里,我想很多人可能已经开始犯了迷糊了:如果要解决一个具体问题,面对这么多的选择,如何决定该使用哪一条呢?

      实际上,当我在上面罗列这些语句的时候,已经有所提示了,不知道你是否注意到了。

      如果你一时无法参透其中奥妙,那也无妨,请听我一一道来便是。

      1、当你希望读取文本文件中的内容的话,第一个括号中不用任何符号包裹,应该使用的是第1条语句;例如:你想显示test.txt中的内容,那么,就使用 for /f %%i in (test.txt) do echo %%i;
      2、当你读取的是命令语句执行结果中的内容的话,第一个括号中的命令语句必须使用单引号包裹,应该使用的是第2条语句;例如:你想显示当前目录下文件名中含有test字符串的文本文件的时候,应该使用 for /f %%i in ('dir /a-d /b *test*.txt') do echo %%i 这样的语句;
      3、当你要处理的是一个字符串的时候,第一个括号中的内容必须用双引号括起来,应该是用的是第3条语句;例如:当你想把bbs.bathome.net这串字符中的点号换为短横线并显示出来的话,可以使用 for /f "delims=. tokens=1-3" %%i in ("bbs.bathome.net") do echo %%i-%%j-%%k 这样的语句。

      很显然,第一个括号里是否需要用符号包裹起来,以及使用什么样的符号包裹,取决于要处理的对象属于什么类型:如果是文件,则无需包裹;如果是命令语句,则用单引号包裹;如果是字符串,则使用双引号括起来。

      当然,事情并不是绝对如此,如果细心的你想到了批处理中难缠的特殊字符,你肯定会头大如斗。

      或许你头脑中灵光一闪,已经想到了一个十分头痛的问题:在第1条语句中,如果文件名中含有空格或&,该怎么办?

      照旧吗?

      拿个叫 test 1.txt 的文件来试试。

      你很快写好了代码,新建文件-->码字-->保存为批处理,前后费时不到1分钟:
    [code17] 

    复制内容到剪贴板 

    代码:

    @echo off
    for /f %%i in (test 1.txt) do echo %%i
    pause

      你兴冲冲地双击批处理,运行后,屏幕上出现了可耻的报错信息:系统找不到文件 test 。

      当你把 test 1.txt 换成 test&1.txt 后,更怪异的事情发生了:CMD窗口在你眼前一闪而过,然后,优雅地消失了。

      你可能觉得自己的代码写错了某些符号,你再仔细的检查了一次,确认没有笔误,然后,你再次双击批处理,结果问题照旧;你开始怀疑其他程序对它可能有影响,于是关掉其他窗口,再运行了一次,问题依旧;你不服气地连续运行了好几次,还是同样的结果。

      怪哉!

      你一拍大腿,猛然想起了一件事:当路径中含有特殊字符的时候,应该使用引号把路径括起来。对,就是它了!

      但是,当你把代码写出来之后,你很快就焉了:for /f %%i in ("test 1.txt") do echo %%i,这不就是上面提到的第3条 for /f 命令的格式吗?批处理会把 test 1.txt 这个文件名识别为字符串啊!

      你百无聊赖地在CMD窗口中输入 for /? ,并重重地敲下了回车,漫无目的地在帮助信息中寻找,希望能找到点什么。

      结果还真让你到了点什么。

      你看到了这样的描述: 

    引用:

            usebackq        - 指定新语法已在下类情况中使用:
                              在作为命令执行一个后引号的字符串并且一个单
                              引号字符为文字字符串命令并允许在 filenameset
                              中使用双引号扩起文件名称。

      但是,通读一遍之后,你却如坠五里雾中,不知所云。

      还好,下面有个例子,并配有简单的说明: 

    引用:


          FOR /F "usebackq delims==" %i IN (`set`) DO @echo %i
        会枚举当前环境中的环境变量名称。

      你仔细对比了for /f语句使用usebackq和不使用usebackq时在写法上的差别,很快就找到了答案:当使用了usebackq之后,如果第一个括号中是一条命令语句,那么,就要把单引号'改成后引号`(键盘左上角esc键下面的那个按键,与~在同一键位上)。

      回过头去再看那段关于usebackq的描述,字斟句酌,反复揣摩,终于被你破译了天机:usebackq 是一个增强型参数,当使用了这个参数之后,原来的for语句中第一个括号内的写法要做如下变动:如果第一个括号里的对象是一条命令语句的话,原来的单引号'要改为后引号`;如果第一个括号里的对象是字符串的话,原来的双引号"要改为单引号';如果第一个括号里的对象是文件名的话,要用双引号"括起来。

      验证一下,把[code17]改写成如下代码:
    [code18] 

    复制内容到剪贴板 

    代码:

    @echo off
    for /f "usebackq" %%i in ("test 1.txt") do echo %%i
    pause

      测试通过!

      此时,你很可能会仰天长叹:Shit,微软这该死的机器翻译!

      至于把[code17]代码中的空格换成&后,CMD窗口会直接退出,那是因为&是复合语句的连接符,CMD在预处理的时候,会优先把&前后两部分作为两条语句来解析,而不是大家想象中的一条完整的for语句,从而产生了严重的语法错误。因为牵涉到预处理机制问题,不属于本节要讨论的内容,在此不做详细讲解。

      这个时候,我们会吃惊地发现,区区一条for语句,竟然有多达6种句型: 

    引用:

      1、for /f %%i in (文件名) do (……)
      2、for /f %%i in ('命令语句') do (……)
      3、for /f %%i in ("字符串") do (……)
      4、for /f "usebackq" %%i in ("文件名") do (……)
      5、for /f "usebackq" %%i in (`命令语句`) do (……)
      6、for /f "usebackq" %%i in ('字符串') do (……)

      其中,4、5、6由1、2、3发展而来,他们有这样的对应关系:1-->4、2-->5、3-->6。

      好在后3种情形并不常用,所以,牢牢掌握好前三种句型的适用情形就可以了,否则,要在这么多句型中确定选择哪一条语句来使用,还真有点让人头脑发懵。

      至于 for /f 为什么要增加usebacq参数,我只为第4条语句找到了合理的解释:为了兼容文件名中所带的空格或&。它在第5、6条语句中为什么还有存在的必要,我也不是很明白,这有待于各位去慢慢发现。

    (七)变量延迟详解[2009.2.12更新]

      变量延迟在for语句中起着至关重要的作用,不只是在for语句中,在其他的复合语句中,它也在幕后默默地工作着,为了突出它的重要性,本节内容在单独的楼层中发出来,希望引起大家的重视。

      对于批处理新手而言,“变量延迟”这个概念很可能闻所未闻,但是,它却像一堵横亘在你前进道路上的无形高墙,你感受不到它的存在,但当你试图往前冲时,它会把你狠狠地弹回来,让你无法逾越、无功而返;而一旦找到了越过它的方法,你就会发现,在for的世界里,前面已经是一片坦途,而你对批处理的理解,又上升到了一个新的境界。

      例如,你编写了这样一个代码:
    [code19] 

    复制内容到剪贴板 

    代码:

    @echo off
    set num=0&&echo %num%
    pause

      你的本意是想对变量num赋值之后,再把这个值显示出来,结果,显示出来的并不是0,而是显示:ECHO 处于关闭状态。

      之所以会出错,是因为“变量延迟”这个家伙在作怪。

      在讲解变量延迟之前,我们需要了解一下批处理的执行过程,它将有助于我们深入理解变量延迟。

      批处理的执行过程是怎样的呢?

      “自上而下,逐条执行”,我想,这个经典的说法大家都已经耳熟能详了,没事的时候倒着念,也还别有一番古韵呢^_^,但是,我想问大家的是,大家真的深刻地理解了这句话的含义了吗?

      “自上而下”,这一条和我们本节的讲解关系不大,暂时略过不说,后一条,“逐条执行”和变量延迟有着莫大的干系,它是我们本节要关注的重点。

      很多人往往认为一行代码就是一条语句,从而把“逐条执行”与“逐行执行”等同起来,这就大错特错了。

      莫非“逐条执行”里暗藏着玄机?

      正是如此。

      “逐条”并不等同于“逐行”。这个“条”,是“一条完整的语句”的意思,并不是指“一行代码”。在批处理中,是不是一条完整的语句,并不是以行来论的,而是要看它的作用范围。

      什么样的语句才算“一条完整的语句”呢?

      1、在复合语句中,整个复合语句是一条完整的语句,而无论这个复合语句占用了多少行的位置。常见的复合语句有:for语句、if……else语句、用连接符&、||和&&连接的语句,用管道符号|连接的语句,以及用括号括起来的、由多条语句组合而成的语句块;
      2、在非复合语句中,如果该语句占据了一行的位置,则该行代码为一条完整的语句。
      例如:
    [code20]

    复制内容到剪贴板 

    代码:

    @echo off
    set num=0
    for /f %%i in ('dir /a-d /b *.exe') do (
        set /a num+=1
        echo num 当前的值是 %num%
    )
    echo 当前目录下共有 %num% exe文件
    dir /a-d /b *.txt|findstr "test">nul&&(
        echo 存在含有 test 字符串的文本本件
    )||echo 不存在含有 test 字符串的文本文件
    if exist test.ini (
        echo 存在 test.ini 文件
    ) else echo 不存在 test.ini 文件
    pause

      上面的代码共有14行,但是只有完整的语句只有7条,它们分别是:

      第1条:第1行的echo语句;
      第2条:第2行的set语句;
      第3条:第3、4、5、6行上的for复合语句;
      第4条:第7行的echo语句;
      第5条:第8、9、10行上用&&和||连接的复合语句;
      第6条:第11、12、13行上的if……else复合语句;
      第7条:第14行上的pause语句。

      在这里,我之所以要花这么长的篇幅来说明一行代码并不见得就是一条语句,是因为批处理的执行特点是“逐条”执行而不是“逐行”执行,澄清了这个误解,将会更加理解批处理的预处理机制。

      在代码“逐条”执行的过程中,cmd.exe这个批处理解释器会对每条语句做一些预处理工作,这就是批处理中大名鼎鼎的“预处理机制”。

      预处理的大致情形是这样的:首先,把一条完整的语句读入内存中(不管这条语句有多少行,它们都会被一起读入),然后,识别出哪些部分是命令关键字,哪些是开关、哪些是参数,哪些是变量引用……如果代码语法有误,则给出错误提示或退出批处理环境;如果顺利通过,接下来,就把该条语句中所有被引用的变量及变量两边的百分号对,用这条语句被读入内存之就已经赋予该变量的具体值来替换……当所有的预处理工作完成之后,批处理才会执行每条完整语句内部每个命令的原有功能。也就是说,如果命令语句中含有变量引用(变量及紧邻它左右的百分号对),并且某个变量的值在命令的执行过程中被改变了,即使该条语句内部的其他地方也用到了这个变量,也不会用最新的值去替换它们,因为某条语句在被预处理的时候,所有的变量引用都已经被替换成字符串常量了,变量值在复合语句内部被改变,不会影响到语句内部的其他任何地方。

      顺便说一下,运行代码[code20]之后,将在屏幕上显示当前目录下有多少个exe文件,是否存在含有 test 字符串的文本文件,以及是否存在 test.ini 这个文件等信息。让很多人百思不得其解的是:如果当前目录下存在exe文件,那么,有多少个exe文件,屏幕上就会提示多少次 "num 当前的值是 0" ,而不是显示1到N(N是exe文件的个数)。

      结合上面两个例子,我们再来分析一下,为什么这两段代码的执行结果和我们的期望有一些差距。

      在[code19]中,set num=0&&echo %num%是一条复合语句,它的含义是:把0赋予变量num,成功后,显示变量num的值。

      虽然是在变量num被赋值成功后才显示变量num的值,但是,因为这是一条复合语句,在预处理的时候,&&后的%num%只能被set语句之前的语句赋予变量num的具体值来替换,而不能被复合语句内部、&&之前的set语句对num所赋予的值来替换,可见,此num非彼num。可是,在这条复合语句之前,我们并没有对变量num赋值,所以,&&之后的%num%是空值,相当于在&&之后只执行了 echo 这一命令,所以,会显示 echo 命令的当前状态,而不是显示变量num的值(虽然该变量的值被set语句改变了)。

      在[code20]中,for语句的含义是:列举当前目录下的exe文件,每发现一个exe文件,变量num的值就累加1,并显示变量num的值。

      看了对[code19]的分析之后,再来分析[code20]就不再那么困难了:第3、4、5行上的代码共同构成了一条完整的for语句,而语句"echo num 当前的值是 %num%"与"set /a num+=1"同处复合语句for的内部,那么,第4行上set改变了num的值之后,并不能对第5行上的变量num有任何影响,因为在预处理阶段,第5行上的变量引用%num%已经被在for之前就赋予变量num的具体值替换掉了,它被替换成了0(是被第2行上的set语句赋予的)。

      如果想让代码[code19]的执行结果中显示&&之前赋予num的值,让代码[code20]在列举exe文件的时候,从1到N地显示exe文件的数量,那又该怎么办呢?

      对代码[code19],可以把用&&连接复合语句拆分为两条单独的语句,写成: 

    复制内容到剪贴板 

    代码:

    @echo off
    set num=0
    echo %num%
    pause

      但是,这不是我们这次想要的结果。

      对这两段代码都适用的办法是:使用变量延迟扩展语句,让变量的扩展行为延迟一下,从而获取我们想要的值。

      在这里,我们先来充下电,看看“变量扩展”有是怎么一回事。

      用CN-DOS里批处理达人willsort的原话,那就是:“在许多可见的官方文档中,均将使用一对百分号闭合环境变量以完成对其值的替换行为称之为“扩展(expansion)”,这其实是一个第一方的概念,是从命令解释器的角度进行称谓的,而从我们使用者的角度来看,则可以将它看作是引用(Reference)、调用(Call)或者获取(Get)。”(见:什么情况下该使用变量延迟?http://www.cn-dos.net/forum/viewthread.php?tid=20733)说得直白一点,所谓的“变量扩展”,实际上就是很简单的这么一件事情:用具体的值去替换被引用的变量及紧贴在它左右的那对百分号。

      既然只要延迟变量的扩展行为,就可以获得我们想要的结果,那么,具体的做法又是怎样的呢?

      一般说来,延迟变量的扩展行为,可以有如下选择:

      1、在适当位置使用 setlocal enabledelayedexpansion 语句;
      2、在适当的位置使用 call 语句。

      使用 setlocal enabledelayedexpansion 语句,那么,[code19]和[code20]可以分别修改为: 

    复制内容到剪贴板 

    代码:

    @echo off
    setlocal enabledelayedexpansion
    set num=0&&echo !num!
    pause

    复制内容到剪贴板 

    代码:

    @echo off
    set num=0
    setlocal enabledelayedexpansion
    for /f %%i in ('dir /a-d /b *.exe') do (
        set /a num+=1
        echo num 当前的值是 !num!
    )
    echo 当前目录下共有 %num% exe文件
    dir /a-d /b *.txt|findstr "test">nul&&(
        echo 存在含有 test 字符串的文本本件
    )||echo 不存在含有 test 字符串的文本文件
    if exist test.ini (
        echo 存在 test.ini 文件
    ) else echo 不存在 test.ini 文件
    pause

      使用第call语句,那么,[code19]和[code20]可以分别修改为: 

    复制内容到剪贴板 

    代码:


    @echo off
    set num=0&&call echo %%num%%
    pause

    复制内容到剪贴板 

    代码:


    @echo off
    set num=0
    for /f %%i in ('dir /a-d /b *.exe') do (
        set /a num+=1
        call echo num 当前的值是 %%num%%
    )
    echo 当前目录下共有 %num% exe文件
    dir /a-d /b *.txt|findstr "test">nul&&(
        echo 存在含有 test 字符串的文本本件
    )||echo 不存在含有 test 字符串的文本文件
    if exist test.ini (
        echo 存在 test.ini 文件
    ) else 不存在 test.ini 文件
    pause

      由此可见,如果使用 setlocal enabledelayedexpansion 语句来延迟变量,就要把原本使用百分号对闭合的变量引用改为使用感叹号对来闭合;如果使用call语句,就要在原来命令的前部加上 call 命令,并把变量引用的单层百分号对改为双层。 其中,因为call语句使用的是双层百分号对,容易使人犯迷糊,所以用得较少,常用的是使用 setlocal enabledelayedexpansion 语句(set是设置的意思,local是本地的意思,enable是能够的意思,delayed是延迟的意思,expansion是扩展的意思,合起来,就是:让变量成为局部变量,并延迟它的扩展行为)。

      通过上面的分析,我们可以知道:

      1、为什么要使用变量延迟?因为要让复合语句内部的变量实时感知到变量值的变化。
      2、在哪些场合需要使用变量延迟语句?在复合语句内部,如果某个变量的值发生了改变,并且改变后的值需要在复合语句内部的其他地方被用到,那么,就需要使用变量延迟语句。而复合语句有:for语句、if……else语句、用连接符&、||和&&连接的语句、用管道符号|连接的语句,以及用括号括起来的、由多条语句组合而成的语句块。最常见的场合,则是for语句和if……else语句。
      3、怎样使用变量延迟?
    方法有两种:
      ① 使用 setlocal enabledelayedexpansion 语句:在获取变化的变量值语句之前使用setlocal enabledelayedexpansion,并把原本使用百分号对闭合的变量引用改为使用感叹号对来闭合;
      ② 使用 call 语句:在原来命令的前部加上 call 命令,并把变量引用的单层百分号对改为双层。 

      “变量延迟”是批处理中一个十分重要的机制,它因预处理机制而生,用于复合语句,特别是大量使用于强大的for语句中。只有熟练地使用这一机制,才能在for的世界中如鱼得水,让自己的批处理水平更上一层楼。很多时候,对for的处理机制,我们一直是雾里看花,即使偶有所得,也只是只可意会难以言传。希望大家反复揣摩,多加练习,很多细节上的经验,是只有通过大量的摸索才能得到的。Good Luck!

    四、翻箱倒柜遍历文件夹:for /r

      (一)for /r 的作用及用法

      按照帮助信息里文绉绉的说法,for /r 的作用是“递归”,我们换一个通俗一点的,叫“遍历文件夹”。

      更详细的解释就是:在下面的语句中,如果“元素集合”中只是一个点号,那么,这条语句的作用就是:列举“目录”及其之下的所有子目录,对这些文件夹都执行“命令语句集合”中的命令语句。其作用与嵌套进 for /f 复合语句的 "dir /ad /b /s 路径" 功能类似。如果省略了“目录”,将在当前目录下执行前面描述的操作。 

    引用:

    for /r 目录 %%i in (元素集合) do 命令语句集合

      先来个代码增强一下印象:
    [code21] 

    复制内容到剪贴板 

    代码:

    @echo off
    for /r d:\test %%i in (.) do echo %%i
    pause

      执行的结果如下所示: 

    引用:

    d:\test\.
    d:\test\1\.
    d:\test\2\.
    d:\test\3\.

      效果就是显示 d:\test 目录及其之下是所有子目录的路径,其效果与 dir /ad /b /s d:\test 类似。若要说到两者的区别,可以归纳出3点:

      1、for /r 列举出来的路径最后都带有斜杠和点号,而 dir 语句则没有,会对获取到的路径进行进一步加工产生影响;
      2、for /r 不能列举带隐藏属性的目录,而 dir 语句则可以通过指定 /a 后面紧跟的参数来获取带指定属性的目录,更加灵活;
      3、若要对获取到的路径进行进一步处理,则需要把 dir 语句放入 for /f 语句中进行分析,写成 for /f %%i in ('dir /ad /b /s') do …… 的形式;由于 for /r 语句是边列举路径边进行处理,所以,在处理大量路径的时候,前期不会感到有停顿,而 for /f 语句则需要等到 dir /ad /b /s 语句把所有路径都列举完之后,再读入内存进行处理,所以,在处理大量路径的时候,前期会感到有明显的停顿。

      第2点差别很容易被大家忽视,导致用 for /r 列举路径的时候会造成遗漏;而第3点则会让大家有更直观的感受,很容易感觉到两者之间的差别。

      要是“元素集合”不是点号呢?那又如何?

      来看看这个代码:
    [code22] 

    复制内容到剪贴板 

    代码:

    @echo off
    for /r d:\test %%i in (a b c) do echo %%i
    pause

      运行的结果是: 

    引用:

    D:\test\1\a
    D:\test\1\b
    D:\test\1\c
    D:\test\2\a
    D:\test\2\b
    D:\test\2\c
    D:\test\3\a
    D:\test\3\b
    D:\test\3\c

      原来,它的含义是:列举 d:\test 及其所有的子目录,对所有的目录路径都分别添加a、b、c之后再显示出来。

      再来看一个代码:
    [code23] 

    复制内容到剪贴板 

    代码:

    @echo off
    for /r d:\test %%i in (*.txt) do echo %%i
    pause

      运行结果是: 

    引用:

    D:\test\test.txt
    D:\test\1\1.txt
    D:\test\1\2.txt
    D:\test\2\a.txt
    D:\test\2\b.txt
    D:\test\3\1.txt

      这段代码的含义是:列举 d:\test 及其所有子目录下的txt文本文件(以.txt结尾的文件夹不会被列出来)。

      我们再回过头来归纳一下这个语句的作用: 

    引用:

    for /r 目录 %%i in (元素集合) do 命令语句集合

      上面语句的作用是:

      1、列举“目录”及该目录路径下所有子目录,并把列举出来的目录路径和元素集合中的每一个元素拼接成形如“目录路径\元素”格式的新字符串,然后,对每一条这样的新
    字符串执行“命令语句集合”中的每一条命令;
      特别的是:当“元素集合”带以点号分隔的通配符?或*的时候,把“元素集合”视为文件(不视为文件夹),整条语句的作用是匹配“目录”所指文件夹及其所有子文件夹下
    匹配的文件;若不以点号分隔,则把“元素集合”视为文件夹(不视为文件);
      2、当省略掉“目录”时,则针对当前目录;
      3、当元素集合中仅仅是一个点号的时候,将只列举目录路径;

      (二)for /r 还是 dir /ad /b /s?列举目录时该如何选择

      前面已经说过,当列举目录时,for /r 和 dir /ad /b /s 的效果是非常类似的,这就产生了一个问题:当我要获取目录路径并进行进一步处理的时候,两者之间,我该如何选择?

      这个问题,前面其实已经有过一些讨论,现在我们再来作详细的分析。

      我们来看一下两者各自的优缺点:

      1、for /r:

        1)优点:

        ① 只通过1条语句就可以同时实现获取目录路径和处理目录路径的操作;
        ② 遍历文件夹的时候,是边列举边处理的,获取到一条路径就处理一条路径,内存占用小,处理大量路径的时候不会产生停顿感;

        2)缺点: 

        ① 不能获取到带隐藏属性的目录,会产生遗漏;
        ② 不能获取带指定属性的目录

      2、dir /ad /s:

        1)优点:

        ① 能一次性获取带任意属性的目录,不会产生遗漏;
        ② 能通过指定不同的参数获取带任意属性的目录,更具灵活性。

        2)缺点:

        ① dir /ad /s 语句仅能获取到目录路径,若要实现进一步的处理,还需要嵌入 for /f 语句中才能实现,写法不够简洁;
        ② 嵌入 for /f 语句之后,需要写成 for /f "delims=" %%i in ('dir /ad /b /s') do …… 的格式,受 for /f 语句运行机制的制约,需要先列举完所有的路径放入内存之后,才能对每一条路径进行进一步的处理,处理大量路径时,内存占用量偏大,并且在前期会产生明显的停顿感,用户体验度不够好;

      综合上述分析,可以做出如下选择:

      1、若仅仅是为了获取某文件夹及其所有子文件夹的路径的话,请选择 dir /ad /b /s 语句;
      2、若需要过滤带隐藏属性的文件夹的话,for /r 和 dir 语句都可以实现,但 for /r 内存占用小,处理速度快,是上上之选;
      3、若需要获取所有文件夹,则除了 dir /ad /b /s 外,别无选择,因为 for /r 语句会遗漏带隐藏属性的文件夹;

      在实际的使用中,我更喜欢使用 for /f 和 dir 的组合,因为它不会产生遗漏,并能给我带来更灵活的处理方式,唯一需要忍受的,就是它在处理大量路径时前期的停顿感,以及在这背后稍微有点偏高的内存占用;在我追求速度且可以忽略带隐藏属性的目录的时候,我会换用 for /r 的方案,不过这样的情形不多——有谁会愿意为了追求速度而容忍遗漏呢?

    五、仅仅为了匹配第一层目录而存在:for /d

      for /d 中 /d ,完整的含义是 /directory,本意是为了处理文件夹,它的完整语句应该是这样的: 

    引用:

    for /d %%i in (元素集合) do 命令语句集合

      当“元素集合”中包含有通配符?或*时,它会匹配文件夹,但是,相比 for /r 而言,这个时候的for /d,其作用就小得可怜了:它仅能匹配当前目录下的第一级文件夹,或是指定位置上的文件夹,而不能匹配更深层次的子文件夹。

      例如:for /d %%i in (d:\test*) do echo %%i 这样的语句 ,会匹配到形如:d:\test、d:\test1、d:\test2之类的文件夹,若不存在这样的路径,将不会有任何回显。

      当“元素集合”中不包含任何的通配符时,它的作用和 "for %%i in (元素集合) do 命令语句集合" 这样的语句别无二致。

      因此,for /d 的角色就变得很微妙了:当“元素集合”中包含通配符?或*时,它的作用就是匹配文件夹,此时,它仅能匹配当前目录下的第一级文件夹,或是指定位置上的文件夹,在层次深度上不及 for /r,但和 for /r 一样的坏脾气:不能匹配带隐藏属性的文件夹;在灵活性上不及for /f和dir的组合;当“元素集合”中不包含任何统配符的时候,它完全是 "for %%i in (元素集合) do ……" 语句的翻版,但是又稍显复杂。

      for /d 的作用是如此有限,我使用的次数是如此之少,以至于我一度找不到它的用武之地,认为它食之无味,弃之可惜,完全是鸡肋一块。

      某年某月,我在cmd窗口里写下了这样的代码:
    [code24] 

    复制内容到剪贴板 

    代码:

    for /d %i in (test*) do @echo %i

      我的本意是想查看在我的临时目录下,长年累月的测试工作到底建立了多少测试文件夹,以便我随后把echo换成rd删除之。这个时候,我发现这条代码是如此的简洁,是 for /r 或 for和 dir /ad /b 的组合所无法替代的(echo换成rd就可以直接删除掉这些测试目录)。

      简洁的代码给我带来的喜悦仅仅持续了短短10几秒的时间,我便开始了迷惘——能用到for /d的类似情形,貌似少之又少且乏善可陈啊。

    六、计数循环:for /l

      /l者,/loop的缩写是也,从鸟语翻译过来,loop就是循环的意思。实际上,所有的for语句,都可以看成是一种“循环”,只是在/l中,特指按照指定次数进行循环罢了。

      for /l 语句的完整格式是这样的:for /l %%i in (x,y,z) do (……),在这个语句中,x、y和z都只能取整数,正负皆可,x指代起始值,y指代步长,z为终止值,具体含义为:从x开始计数,以y为步长,直至最接近z的那个整数值为止,这之间有多少个数,do后的语句就执行多少次。

      举个具体的例子:
    [code25] 

    复制内容到剪贴板 

    代码:

    for /l %%i in (1,2,10) do echo bathome

      在以上的代码中,初始值是1,步长为2,终止值为10,表明计数从1开始,每隔2个数计算一次,直至最接近10的那个整数,罗列出来,就是1,3,5,7,9,再下一个就是11,超过10了,不再计算在内,所以,do后的语句只执行5次,将连续显示5个bathome。

      实际上,x,y和z的值可正可负,甚至为0,限制非常宽松:

      1、步长y的值不能为0;
      2、当步长y的值为正整数时,终止值z不能小于初始值x;
      3、当步长y的值为负整数的时候,终止值z不能大于初始值x。

      换而言之,必须保证in和do之间能取到一个有效的数组序列。

      例如:
    [code26] 

    复制内容到剪贴板 

    代码:

    for /l %%i in (-1,2,5) do echo bathome

    [code27] 

    复制内容到剪贴板 

    代码:

    for /l %%i in (5,-2,-1) do echo bathome

      以上两条代码的功能完全一样,都将显示4次bathome,区别就在于[code26]是正序计算,而[code27]是逆序计数而已。

      以下几条代码都是有问题的:
    [code28] 

    复制内容到剪贴板 

    代码:

    for /l %%i in (1,0,1) do echo bathome

    [code29] 

    复制内容到剪贴板 

    代码:

    for /l %%i in (2,1,1) do echo bathome

    [code30] 

    复制内容到剪贴板 

    代码:

    for /l %%i in (1,-1,2) do echo bathome

    其中,[code28]违反了步长不能为0的限制,将陷入无限循环中;[code29]和[code30]都犯了同样的错误:无法获得有效的数列元素,导致in和do之间取到的值为空元素,从而使得整条for语句无从执行。

      当大家明白了 for /l 的具体功能之后,是否会想到了与它有异曲同工之妙的goto循环语句呢?似乎,for /l 和 goto 循环语句可以相互替换?

      一般而言,for /l语句可以换成goto循环,但是,goto循环并不一定能被 for /l 语句替换掉。具体原因,请大家仔细想想,我在此不再详细解说,只是就大家非常关心的一个问题提供一个简洁的答案,那就是:什么时候该用 for /l 计数循环,而什么时候又该用goto条件循环?

      答案非常简单:当循环次数确定的时候,首选 for /l 语句,也可使用goto语句但不推荐;当循环次数不确定的时候,用goto语句将是唯一的选择,因为,这个时候需要用if之类的条件语句来判断何时结束goto跳转。

     后记:

      当Windows为我们打开了五彩缤纷的图形窗口的时候
      DOS命中注定会陨落
      CMD毫无悬念将萎缩
      批处理逐渐趋向无声无息
      而powershell的到来,无疑会让更多的人忘记批处理
      这是一门即将失传的技艺
      这是一块行将就木的领域
      然而,命令行工具仍然具有批量处理一切的巨大威力
      字符界面仍然是高效操作的代名词
      曾为批处理的方便灵活而击节赞赏
      曾被批处理的简洁快速深深折服
      一直以来,总想为批处理的推广做些什么
      于是,从在CN-DOS里尽职尽责地为大家解答疑问,到创办了自己的论坛专职答疑解惑,再到无怨无悔地码字写教程,一步步走来,喜怒哀愁,五味杂陈
      直至如今辞去站长等一切管理职务,逐渐淡出批处理圈子
      梦依旧在,只是,心有余而力渐有不足
      这篇从入门到精通的教学帖,从200810月开贴到现在,不知不觉拖拖拉拉竟然过去了两年有余
      每每看到跟帖的会员在问什么时候有更新
      心中总有一丝愧疚
      今天,终于抽空对它做个了断
      只是,年年岁岁花相似,岁岁年年人不同
      繁杂的事务使我已不再有当初的心境
      for /l 部分总有虎头蛇尾的感觉
      只能向各位说声抱歉了
      在我彻底淡出批处理圈子之前
      我只能尽我所能地向各位倾我所学了

    -========================原作者不详。。。。。

    展开全文
  • windows bat(批处理)——IF详解

    千次阅读 2015-03-12 11:27:45
    摘要:本文介绍了windows bat中IF语句的语法,包括3中基本形势和扩展IF语句   1. IF & IF not if 和 if not 有都有3中形势: IF [NOT] ERRORLEVEL number do command  IF [NOT] string1==string2 ...
    摘要:本文介绍了windows bat中IF语句的语法,包括3中基本形势和扩展IF语句
     
    1. IF & IF not
    if  和 if not 有都有3中形势:
    IF [NOT] ERRORLEVEL number do command 
    IF [NOT] string1==string2 do command 
    IF [NOT] EXIST filename do command
      NOT               指定只有条件为 false 的情况下,Windows 才
                        应该执行该命令。
     
      ERRORLEVEL number 如果最后运行的程序返回一个等于或大于
                        指定数字的退出代码,指定条件为 true。
     
      string1==string2  如果指定的文字字符串匹配,指定条件为 true。
     
      EXIST filename    如果指定的文件名存在,指定条件为 true。
     
      command           如果符合条件,指定要执行的命令。如果指定的
                        条件为 FALSE,命令后可跟 ELSE 命令,该命令将
                        在 ELSE 关键字之后执行该命令。
    1.1 IF [NOT] string1==string2    do command
    注意是 string, 同时要保持string1 和string2 的格式相同
    如:
    [python] 
    if "%1"=="a" format a:  
    if {%1}=={} goto noparms  
    if {%2}=={} goto noparms  
     
    1.2 IF [NOT] EXIST filename      do command
    如果有指定的文件,则条件成立,运行命令,否则运行下一句。
    [python] 
    1.   
    if exist config.sys edit config.sys  
    2.   
    if exist %1.obj link %1.obj  
    else pause & edit %1.asm   
    3.   
        IF EXIST filename. (  
            del filename.  
        ) ELSE (  
            echo filename. missing.  
        )  
    ELSE 子句必须出现在同一行上的 IF 之后
    由于 del 命令需要用新的一行终止,因此以下子句不会有效:
    [python] 
    IF EXIST filename. del filename. ELSE echo filename. missing  
     
    由于 ELSE 命令必须与 IF 命令的尾端在同一行上,以下子句也
    不会有效:
     
    [python] 
    IF EXIST filename. del filename.  
    ELSE echo filename. missing  
     
    如果都放在同一行上,以下子句有效:
    [python] 
    IF EXIST filename. (del filename.) ELSE echo filename. missing  
     
    1.3 IF [NOT] ERRORLEVEL number do command
    如果返回码等于指定的数字,则条件成立,运行命令,否则运行下一句。
    如if errorlevel 2 goto x2  
    DOS程序运行时都会返回一个数字给DOS,称为错误码errorlevel或称返回码,常见的返回码为0、1。
     
    2. IF扩展
    如果命令扩展被启用,IF 会如下改变:
     
        IF [/I] string1 compare-op string2 command
        IF CMDEXTVERSION number command
        IF DEFINED variable command
     
    (1) IF [/I] string1 compare-op string2 command
    compare-op 可以是:
     
        EQU - 等于
        NEQ - 不等于
        LSS - 小于
        LEQ - 小于或等于
        GTR - 大于
        GEQ - 大于或等于
     
     /I 开关(如果指定)说明要进行的字符串比较不分大小写。
    /I 开关可以用于 IF 的 string1==string2 的形式上。这些比较都是通用的;原因是,如果 string1 和 string2 都是由数字组成的,字符串会被转换成数字,进行数字比较。
    (2)IF CMDEXTVERSION number command
    CMDEXTVERSION 条件的作用跟 ERRORLEVEL 的一样,除了它是在跟与命令扩展有关联的内部版本号比较。第一个版本是 1。每次对命令扩展有相当大的增强时,版本号会增加一个。命令扩展被停用时,CMDEXTVERSION 条件不是真的。
     
    如果已定义环境变量,DEFINED 条件的作用跟 EXIST 的一样,除了它取得一个环境变量,返回的结果是 true。
     
    如果没有名为 ERRORLEVEL 的环境变量,%ERRORLEVEL%
    会扩充为 ERROLEVEL 当前数值的字符串表达式;否则,您会得到
    其数值。运行程序后,以下语句说明 ERRORLEVEL 的用法:
     
        goto answer%ERRORLEVEL%
        :answer0
        echo Program had return code 0
        :answer1
        echo Program had return code 1
     
    您也可以使用以上的数字比较:
     
        IF %ERRORLEVEL% LEQ 1 goto okay
     
    如果没有名为 CMDCMDLINE 的环境变量,%CMDCMDLINE%
    将在 CMD.EXE 进行任何处理前扩充为传递给 CMD.EXE 的原始
    命令行;否则,您会得到其数值。
     
    如果没有名为 CMDEXTVERSION 的环境变量,
    %CMDEXTVERSION% 会扩充为 CMDEXTVERSION 当前数值的
    字串符表达式;否则,您会得到其数值。
    展开全文
  • 批处理中的if语句

    2011-10-13 11:06:00
    判断两个字符串是否相等,if"字符串1"=="字符串2" command 语句 注意:在"字符串1"=="字符串2"中,是两个连续的"=" 例1 @echo off set /p var1=请输入第一...

    if条件语句

    1。判断两个字符串是否相等,if"字符串1"=="字符串2" command 语句
    注意:在"字符串1"=="字符串2"中,是两个连续的"="

    例1
    @echo off
    set /p var1=请输入第一个比较的字符:
    set /p var2=请输入第二个比软的字符:
    if "%var1%"=="%var2%" (echo 输入的两个字符相同) else echo 输入的两个字符不相同
    pause

    执行后会要求你输入两个字符串,然后批处理判断它俩是否相同。在判断字符串是否相等的时候,if是会区分大小写
    的,请看,

    例2
    @echo off
    if "a"=="A" (echo 输入的两个字符相同) else echo 输入的两个字符不相同
    pause

    执行后会显示:输入的两个字符不相同
    如果我们不想让它区分大小写,则可以加上/i 参数。再看下面这个例子,

    例3
    @echo off
    if /i "a"=="A" (echo 输入的两个字符相同) else echo 输入的两个字符不相同
    pause

    这次执行后会显示:输入的两个字符相同
    ------------------------------------------------------------------------------------------------------


    2。判断两个数值是否相等,if 数值1 equ 数值2 command 语句
    语句中的equ 表示相等的意思,判断两个数值之间的大小关系还有以下关系符号:

    中文含义 关系符 英文解释
    等于 equ equal
    大于 gtr greater than
    大于或等于 geq greater than or equal
    小于 lss less than
    小于或等于 leq less than or equal
    不等于 neq no equal

    我们还是来看个例子,

    例4
    @echo off
    set /p var=请输入一个数字:
    if %var% geq 10 (echo 此数大于或等于10) else echo 此数小于10
    pause

    注意哦,批处理中的大于号,小于号,等于号等等都不能用:“>” “<” “=” 这些符号,而要用像"gtr"这类
    的。


    ☆注意:if 比较字符串与比较数字 之间的区别,它们的区别体现在引号""上面,请看下面的例子

    【example 1】
    @echo off
    if "12" lss "4" (echo 12竟然小于4哦?) else echo 12当然不会小于4的!
    pause

    执行的结果是:12竟然小于4哦?


    【example 2】
    @echo off
    if 12 lss 4 (echo 12竟然小于4哦?) else echo 12当然不会小于4的!
    Pause

    执行的结果是:12当然不会小于4的!

    为什么【example 1】中加了双引号""会出错呢?

    原因如下:
    如果要比较的两个元素加了双引号"",那么会被当成是字符的比较。两个元素作比较的流程是:先比较两个元素
    的首位,如果首位相同,再比较第二位,如果第二位相同,再比较第三位。。。依此,在【example 1】if "12" lss
    "4" 语句中,实质是1与4的比较,1当然小于4,所以执行了后面的命令:echo 12竟然小于4哦?

    ☆建议:如果是字符串的比较就使用双引号"" 是数字的比较就不用双引号了!
    ------------------------------------------------------------------------------------------------------


    3。判断判断驱动器,文件或文件夹是否存在,if exist filename command 语句
    我们来瞧瞧这个判断驱动器,文件或者文件夹是否存在的语句,这里if exist filename 是表示:存在 filename的
    意思。

    例5
    @echo off
    if exist "e:" (echo e盘存在) else echo e盘不存在
    pause>nul

    这里是判断e: 是否存在!

    例6
    @echo off
    if exist d:\123.bat (echo 123.bat文件存在!) else echo 123.bat文件不存在!
    pause

    这个例子是用来判断123.bat文件是否存在的,但并不严谨!如果123.bat是一个文件夹而不是一个文件时,上面的判
    断就不行了!那么如何判断指定的文件123.txt是否存在?请看:

    @echo off
    dir /a-d d:\123.bat >nul 2>nul
    if %errorlevel%==0 (echo 123.bat文件存在!) else echo 123.bat文件不存在!
    Pause

    先用dir的/a-d参数去除123.bat的目录属性,指定说明要搜索的123.bat是文件而不是文件夹,并把结果(包括正确
    和错误)屏蔽(>nul 2>nul),如果dir找到了文件123.bat,那么其errorlevel值(dir命令的退出编码)会被设为0,否
    则为1则是没有此文件。当然也可以用||和&&来判断。关于为什么要用if %errorlevel%==0 而不用if errorlevel 0
    呢?在后面if errorlevel中会有说明!

    例7
    @echo off
    if exist test\ (echo test 是文件夹) else echo test 是文件
    pause

    这里是判断文件夹是否存在。对于文件夹存在的判断,我们不可以用以下两种写法:

    第①种
    @echo off
    if exist test\. (echo test 是文件夹) else echo test 是文件
    pause


    第②种
    @echo off
    if exist test\nul (echo test 是文件夹) else echo test 是文件
    pause
    ------------------------------------------------------------------------------------------------------


    4。判断变量是否已经定义,if defined 变量 command 语句
    这是一个判断变量是否已被定义的语句,我们还是先看例子,

    例8
    @echo off
    if defined a (echo 变量 a 已定义) else (echo 变量 a 没有被定义)
    pause
    执行后显示:变量 a 没有被定义

    例9
    @echo off
    set a=
    if defined a (echo 变量 a 已定义) else (echo 变量 a 没有被定义)
    pause
    执行后显示:变量 a 没有被定义

    注意:set a=这后面是没有空格的。

    例10
    @echo off
    set a=10
    if defined a (echo 变量 a 已定义) else (echo 变量 a 没有被定义)
    pause
    执行后显示:变量 a 已定义

    看了上面三个例子,你应该发现点什么了吧?现在我们应该知道了:当变量不存在或是值为空时,变量则为未定
    义。
    当我们用if defined 变量 command 语句判断变量是否被定义时,请注意 变量 为不使用引导符号%的变量名,不
    能用写为%变量%,否则出错。

    大家来试一下下面的这两个例子,

    例11
    @echo off
    set var1=5
    if defined var1 (echo 变量var1已定义) else (echo 变量var1没有被定义)
    set /p var2=请输入一个数字:
    if defined %var2% (echo 变量var2已定义) else (echo 变量var2没有被定义)
    pause

    例12
    @echo off
    set var1=5
    if defined var1 (echo 变量var1已定义) else (echo 变量var1没有被定义)
    set /p var2=请输入一个数字:
    if defined var2 (echo 变量var2已定义) else (echo 变量var2没有被定义)
    pause

    注意例11和例12哦:一个是%var2%而另一个是var2
    ------------------------------------------------------------------------------------------------------


    5。判断上个命令的反回值,if errorlevel 数值 command 语句
    这个语句是用于判断上一个命令执行的返回值errorlevel,我们还是先来看看例子,

    例13
    @echo off
    net user
    if %errorlevel% == 0 (echo net user 命令执行成功) else (echo net user 命令执行失败)
    Pause

    注意:%errorlevel% 这是个系统变量,所以用两个%括起来,这里的==为两个连续的=
    也许有些朋友说我上面的例子是不是写错了?按照语法应该写成“if errorlevel 0”才对的呀。
    如果你是这样用的话,那你就错了,还真不信呀?OK,我们来设计个实验看看

    例14
    @echo off
    set /p input=请输入任意一条命令:
    if errorlevel 0 (echo %input% 命令执行成功) else (echo %input% 命令执行失败)
    pause
    用这种语法,不管你前面的命令,是否执行成功,它都会认为命令成功了。何解?


    if errorlevel 语句的特点:
    当使用 if errorlevel 0 cmmand 句式时,它的含义是:如果返回的错误码值大于或等于0 的时候,将执行cmmand
    操作;
    当使用 if %errorlevel%==0 cmmand 句式时,它含义是:如果返回的错误码值等于0 的时候,将执行cmmand操作。

    一般上一条命令的执行结果返回的值只有两个,"成功"用0 表示 "失败"用 1 表示,实际上,errorlevel 返回值可
    以在0~255 之间,
    例如xcopy 默认的errorlevel 值就有5 个,分别表示5 种执行状态:

    0复制文件成功
    1 未找到复制文件
    2 用户通过CTRL C 终止了xcopy操作
    4 出现了初始化错误
    5 出现了磁盘写入错误
    ------------------------------------------------------------------------------------------------------


    对于if 条件语句,常用的也就上面那5条吧,下面我们来看一下它的两种格式:

    if条件语句的完整格式是:if 条件表达式 (语句1) else (语句2)
    它的含义是:如果 条件表达式 成立,就执行 语句1,否则,将执行 语句2。? else后的 语句2 也可以不用括号括
    起。

    if条件语句的简单格式是:if 条件表达式 (语句)
    它的含义是:如果 条件表达式 成立,将执行 语句,否则,什么都不做。条件表达式后的 语句 也可以不用括号括
    起。

    例15
    @echo off
    if exist "d:\123.txt" (del "d:\123.txt")
    pause

    你也可以写成下面这样

    例16

    @echo off
    if exist "d:\123.txt" del "d:\123.txt"
    pause
    ------------------------------------------------------------------------------------------------------


    补充1:if not 语句
    对于if 语句前面的5种基本语法,都可以加上not参数,如
    1。if not "字符串1"=="字符串2" command 语句;
    2。if not数值1 equ 数值2 command 语句;
    3。If not exist filename command 语句;
    4。if not defined 变量 command 语句;
    5。if not errorlevel 数值 command 语句。

    在if 条件表达式 (语句) 语句,如没有not参数,默认是判断条件成立时,执行语句;如有not参数,判断条件失
    败时,执行语句。

    我们看一下下面的例子:

    例17
    @echo off
    if exist "c:\" (echo C盘存在) else echo C盘不存在
    pause
    执行后显示:C盘存在

    例18
    @echo off
    if not exist "c:\" (echo C盘存在) else echo C盘不存在
    pause
    执行后显示:C盘不存在

    不会吧,例18中执行后显示:C盘不存在,这简值是在说瞎话了,那到底是什么回事呢?

    if not exist "c:\" (echo C盘存在) else echo C盘不存在
    此语句中文意思:如果不存在C:\ 就执行显示C盘存在;否则<指的是存在C:\>就执行显示C盘不存在。
    注:if exist 意为如果存在,那么if not exist就是如果不存在

    你的C盘当然是实实在在存在的啦,根椐上面的中文分得知,那执行例18后就显示为:C盘不存在 通过分析例18,你
    应该明白if语句中not参数是怎么用了吧!
    ------------------------------------------------------------------------------------------------------


    补充2:IF语句嵌套的写法,我们先来看看

    例1
    @echo off
    set a=55
    if %a% geq 50 (
    if %a% geq 80 (
    if %a% geq 100 (
    echo a大于等于100
    ) else echo a小于100
    ) else echo a小于80
    ) else echo a小于50
    pause

    这是一种比较规范的写法,那这种写法是怎样写的呢?那我们一步步的来:

    第一步:
    if %a% geq 50 ( ) else echo a小于50

    第二步:在第一步geq 50 后面的括号()里按两下回车,主要是空两行出来。
    if %a% geq 50 (
    if %a% geq 80 ( )else echo小于80
    ) else echo a小于50

    第三步:在第二步geq 80 后面的括号()里按两下回车,主要是空两行出来。
    if %a% geq 50 (
    if %a% geq 80 (
    if %a% geq 100 ( ) else echo a小于100
    )else echo小于80
    ) else echo a小于50

    第四步:在第三步geq 100 后面的括号()里按两下回车,主要是空两行出来。
    if %a% geq 50 (
    if %a% geq 80 (
    if %a% geq 100 (
    echo a大于等于100
    ) else echo a小于100
    )else echo小于80
    ) else echo a小于50

    上面的代码中,if %a% 和 )else 要适当的缩进,以达到写书清晰!
    ------------------------------------------------------------------------------------------------------

    展开全文
  • 批处理for语句详解教程

    千次阅读 2012-03-29 22:41:31
     在批处理中,for 是最为强大的命令语句,它的出现,使得解析文本内容、 遍历文件路径、数值递增/递减等操作成为可能;配合if、call、goto 等流程控制 语句,更是可以实现脚本复杂的自动化、智能化操作;合理使用...
  • 有时编写bat批处理时会用到判断当前是否为管理员权限以及自动以管理员权限运行 在这里记录几个常用的方法 1.判断是否以管理员身份运行 这个操作方式比较多,核心思想就是试图访问需要管理员身份才可以访问的资源,...
  • bat中if语句的用法

    万次阅读 多人点赞 2014-07-15 16:10:00
    “if”语句批处理中使用的是比较广泛的,例如要查看某个文件,则首先要确定该文件存在才可以查看,否则MS-DOS会抛出错误信息,这个时候就可以使用“if”语句进行判断。“if”命令语句是通过条件成立与否来决定语句...
  • 批处理】bat常用语句及使用技巧

    千次阅读 2019-01-02 23:52:09
    语句 注释 在echo off的情况下,两者都可以用。在echo on的情况下,只有@rem可以用。 pause是等待输入空格 rem 注释1 @rem 注释2 输出 “”适用于对象,如果输出加上“”,就是直接输出双引号的意思。而...
  • mybatis设置update批处理语句

    千次阅读 2018-07-24 21:22:37
    mybatis学习之路----批量更新数据两种方法效率对比 2017年09月13日 21:58:06 阅读数:27235 点滴记载,点滴进步,愿自己更上一层楼。...另一种 用mysql的case when 条件判断变相的进行批量更新 ...
  • 一些关于批处理条件语句的例子,资源来自网络
  • 批处理语法语句

    2011-08-30 11:32:13
    第一部分:批处理的专用命令 批处理文件是将一系列命令按一定的顺序集合为一个可执行的文本文件,其扩展名为BAT。这些命令统称批处理命令,下面我就来给大家介绍一下批处理的命令。 1、 REM REM 是个注释...
  • 批处理语句结构)

    2017-09-29 11:46:00
    批处理是一门简单的脚本语言,虽然不能独当一面,但可以作为工作中的辅助工具  和其他语言相比,批处理语言有其先天性的... if ----- 条件判断语句(选择结构)  判断信息是否相等(==) 判断错误级别(%errorleve...
  • bat 批处理文件 中if else 语句写法

    万次阅读 2017-08-21 17:46:55
    使用bat批处理文件if else 语句需要注意语法。 @echo off echo %1 if "%1"=="ker" ( echo kernel echo kernel2 echo kernel3 ) else ( echo dtbc echo dtbc1 echo dtbc2 echo ...
  • 批处理判断字符串不等于写法

    千次阅读 2020-07-22 15:33:17
    不等于用NEQ 例如:参数branch不等tags时,执行jenkins_build方法 if “%rows%” == “1” (if %branch% NEQ tags (goto jenkins_build) else (goto end)) else (goto end) 其中NEQ两边的值不能加双引号
  •  2、可执行计划:SQL SERVER将批处理语句编译成一个可执行单元。执行计划中的语句每次招待一条。  3、一个批处理以GO结束。 二、建立批处理时应遵循以下规则:  1、所有批处理必须以CREATE语句开头。  2、不...
  • bat 判断语句中的比较

    千次阅读 2018-09-23 01:22:49
    EQU - 等于 NEQ - 不等于 LSS - 小于 LEQ - 小于或等于 GTR - 大于 GEQ - 大于或等于
  • 大纲 一 前言 二 for语句的基本用法 三 for /f (delims、tokens、skip、...在批处理中,for是最为强大的命令语句,它的出现,使得解析文本内容、遍历文件路径、数值递增/递减等操作成为可能;配合if、call、goto...
  • 批处理判断操作系统是32位还是64位,并注册install服务。分类: @echo offif /i “%PROCESSOR_IDENTIFIER:~0,3%” == “X86” goto 1 /////通过参数判定操作系统位数,并跳转 if /i “%PROCESSOR_IDENTIFIER:~0,...
  • 批处理判断是否以管理员权限

    千次阅读 2018-08-09 15:52:58
    TITLE 判断DOS批处理文件是否以管理员运行 ::该方法是在一些流氓软件的看到的.. 很是不错 ::【&amp;&amp;】 连接两个命令,当&amp;&amp;前的命令成功时,才执行&amp;&amp;后的命令。 ::【|...
  • tokens=3 代表第三列 skip=1 代表越过第一行 version.mk MACHINE_TYPE = 12 VERSION_NUMBER = 1.1.1 MODEL_NAME = KK 如下代码的效果就是把第一行 MACHINE_TYPE = 12 中的 12 取出来 如下代码的效果就是把第二行 ...
  •  对于这个问题,很多人会毫不犹豫地选择 if "%str%"=="" …… 的句式,在早期的批处理中,还可以看到这样的语句:if [%str%]==[],有人把这两种写法称为“防空字符”。  可是,这样做真的能在各种复杂的情况下...
  • 首先是cmd命令: #以默认浏览器启动百度网站# start ... #启动谷歌浏览器访问百度# start chrome ...保存,修改文件后缀为.bat,然后在cmd命令窗口执行...是条件语句,注意空格问题,else前后都必须加空格,否则无法识别
  • 那样的话我自己都会觉得自己太2了,于是想到用批处理应该可以判断操作系统版本,而针对版本执行对应版本的语句。我自己没搞过,当然只能在网上搜索了,找了好多网站,发现了一共3种类似的方法,于是稍加修改整理,发...
  • 1. 条件判断 EQU - 等于 NEQ - 不等于 LSS - 小于 LEQ - 小于或等于 GTR - 大于 GEQ - 大于或等于 程序代码 @echo off set /a a=1,b=2 if %a% equ %b% (echo yes) else (echo no) if %a% neq %b% (echo yes) else...
  • SQL语句批处理

    千次阅读 2017-11-12 14:13:03
    DatabaseMetaData类的supportsBatchUpdates方法用于判断数据库是否支持sql语句批处理 Statement的addBatch()方法添加一个sql,如果一次执行多条sql语句,就需要多次调用addBatch()方法 Statement的...
  • [批处理]语句结构

    2010-06-03 01:57:32
    类似于C语言,批处理也有它的语句结构。批处理语句结构主要有选择结构(if语句)、循环结构(for语句)等。 【 if语句(选择结构) 】 if语句实现条件判断,包括字符串比较、存在判断、定义判断等。通过条件判断,if...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 24,648
精华内容 9,859
关键字:

批处理判断语句