admin 管理员组

文章数量: 887019


批处理文件是无格式的文本文件,本质就是一堆DOS命令按一定顺序排列而形成的集合, 它英文译为BATCH,文件扩展名为 .bat 或 .cmd。在命令提示下键入批处理文件的名称,或者双击该批处理文件,系统就会调用Cmd.exe按照该文件中各个命令出现的顺序来逐个运行它们。使用批处理文件(也被称为批处理程序或脚本),可以简化日常或重复性任务。

 

 

 

基础篇

一. 简单批处理内部命令简介

echo、@、call、pause、rem()是批处理文件最常用的几个命令,if goto choice for是批处理文件中比较高级的命令。

 

1.echo
echo 表示显示此命令后的字符
echo off
表示在此语句后所有运行的命令都不显示命令行本身
echo [{on|off}] [message]

 

2.@ 命令
表示不显示@后面的命令,(只能影响当前行)

Sample:@echo off / echo hello world

 

3.goto命令
指定跳转到标签,找到标签后,程序将处理从下一行开始的命令。
语法:goto label (label是参数,用“:字符串”来定义,指定所要转向的批处理程序中的行,所在行不被执行。)

注意:
(1)
标号前是ASCII字符的冒号":",冒号与标号之间不能有空格。
(2) 标号的命名规则与文件名的命名规则相同。
(3) DOS支持最长八位字符的标号,当无法区别两个标号时,将跳转至最近的一个标号。

4.Rem命令小技巧: 用::代替rem)
注释命令,在C语言中相当与/*--------*/,它并不会被执行,只是起一个注释的作用,便于别人阅读和你自己日后修改。

5.Pause命令
暂停,等待按键继续,可用来回显调试使用。

 

6.Call命令
从一个批处理程序调用另一个批处理程序,并且不终止父批处理程序,执行完子批处理文件后将返回到父文件并执行父文件的后续命令。如果在脚本或批处理文件外使用 Call,它将不会在命令行起作用。
语法
call [Drive:][Path] FileName [BatchParameters] [:label [arguments]
参数
[Drive:}[Path] FileName
指定要调用的批处理程序的位置和名称。filename 参数必须具有 .bat 或 .cmd 扩展名。

 

7.start命令
调用外部程序,所有的DOS命令和命令行程序都可以由start命令来调用。
入侵常用参数:
MIN 开始时窗口最小化
SEPARATE 在分开的空间内开始 16 位 Windows程序
HIGH 在 HIGH 优先级类别开始应用程序
REALTIME 在 REALTIME 优先级类别开始应用程序
WAIT 启动应用程序并等候它结束
parameters 这些为传送到命令/程序的参数
执行的应用程序是 32-位 GUI 应用程序时,CMD.EXE 不等应用程序终止就返回命令提示。如果在命令脚本内执行,该新行为则不会发生。


8.choice 命令

choice 使用此命令可以让用户输入一个字符,从而运行不同的命令。使用时应该加/c:参数,c:后应写提示可输入的字符,之间无空格。它的返回码为1234……

(注意:choice命令为DOS或者Windows系统提供的外部命令,不同版本的choice命令语法会稍有不同,请用choice /?查看用法。)

 

choice的命令语法(该语法为Windows 2003中choice命令的语法,其它版本的choice的命令语法与此大同小异):
CHOICE [/C choices] [/N] [/CS] [/T timeout /D choice] [/M text]
描述:
该工具允许用户从选择列表选择一个项目并返回所选项目的索引。


参数列表:
  /C choices 指定要创建的选项列表。默认列表是 "YN"。
  /N 在提示符中隐藏选项列表。提示前面的消息得到显示,选项依旧处于启用状态。
  /CS 允许选择分大小写的选项。在默认情况下,这个工具是不分大小写的。
  /T timeout 做出默认选择之前,暂停的秒数。可接受的值是从 0到 9999。如果指定了                0,就不会有暂停,默认选项会得到选择。
  /D choice 在nnnn 秒之后指定默认选项。字符必须在用 /C 选项指定的一组选择中;         同 时,必须用 /T 指定 nnnn。
  /M text 指定提示之前要显示的消息。如果没有指定,工具只显示提示。
  /? 显示帮助消息。

注意:
ERRORLEVEL 环境变量被设置为从选择集选择的键索引。列出的第一个选择返回 1,第二个选择返回 2,等等。如果用户按的键不是有效的选择,该工具会发出警告响声。如果该工具检测到错误状态,它会返回 255 的ERRORLEVEL 值。如果用户按 Ctrl+Break 或 Ctrl+C 键,该工具会返回 0的 ERRORLEVEL 值。在一个批程序中使用 ERRORLEVEL 参数时,将参数降序排列。

示例:
CHOICE /?
CHOICE /C YNC /M "
确认请按 Y,否请按 N,或者取消请按 C。"
CHOICE /T 10 /C ync /CS /D y
CHOICE /C ab /M "选项 1 请选择a,选项 2 请选择 b。"
CHOICE /C ab /N /M "选项 1 请选择 a,选项 2 请选择 b。"
Sample:
Sample.bat的内容如下:
@echo off
choice /c:dme defrag,mem,end
if errorlevel 3 goto defrag (应先判断数值最高的错误码)
if errorlevel 2 goto mem
if errotlevel 1 goto end

:defrag
c:dosdefrag
goto end
:mem
mem
goto end
:end
echo good bye

此文件运行后,将显示defrag,mem,end[D,M,E]? 用户可选择d m e ,然后if语句将作出判断,d表示执行标号为defrag的程序段,m表示执行标号为mem的程序段,e表示执行标号为end的程序段,每个程序段最后都 以goto end将程序跳到end标号处,然后程序将显示good bye,文件结束。

 

9.If命令

if 表示将判断是否符合规定的条件,从而决定执行不同的命令。 有三种格式:
(1)、if [not] "参数" == "字符串"  待执行的命令

如if "%1"=="a" format a:
if {%1}=={} goto :noparms
if {%2}=={} goto :noparms

注意:为了防止参数为空的情况,一般会将字符串用双引号

(2)、if [not] exist 文件名  待执行的命令
如果[没]有指定的文件,则条件成立,运行命令,否则运行下一句。
如if exist config.sys edit config.sys如果存在文件则对其进行编辑

(3)、if errorlevel / if not errorlevel  数字  待执行的命令
如果返回码等于指定的数字,则条件成立,运行命令,否则运行下一句。
DOS程序运行时都会返回一个数字给DOS,称为错误码errorlevel或称返回码,常见的返回码为0、1。

 

10.for命令(详解见进阶篇)
for 命令是一个比较复杂的命令,主要用于参数在指定的范围内循环执行命令。
在批处理文件中使用 FOR 命令时,指定变量请使用%%variable

for{%variable|%%variable} in (set) do command [command-parameters]
%variable 指定一个单一字母可替换的参数。
(set) 指定一个或一组文件,可以使用通配符。
command 指定对每个文件执行的命令。
command-parameters 为特定命令指定参数或命令行开关。
在批处理文件中使用 FOR 命令时,指定变量请使用%%variable而不要用 %variable。变量名称是区分大小写的,所以 %i 不同于 %I

 

运行机理:for语句依次提取set中的每一个元素,把它的值赋予形式变量variable,带到do后的command中参与命令的执行;并且每次只提取一个元素,然后执行一次do后的命令语句,而无论这个元素是否被带到command中参与了command的运行;当执行完一次do后的语句之后,再提 取set中的下一个元素,再执行一次command,如此循环,直到set中的所有元素都已经被提取完毕,该for语句才宣告执行结束;

 

 

 

 

 

二.如何在批处理文件中使用参数

批处理文件使用参数(相当于DOS命令的命令行参数),需要用到一个参数表示符“%”。
%[1-9]表示参数,参数是指在运行批处理文件时在文件名后加的以空格(或者Tab)分隔的字符串。变量可以从%0到%9,%0表示批处理命令本身,其它参数字符串用%1到%9顺序表示。当有多个参数时需要用shift来移动,这种情况并不多见,我们就不考虑它了。
例:C:根目录下有一批处理文件名为f.bat,内容为:
@echo off
format %1

如果执行C:\>f a:
那么在执行f.bat时,%1就表示a:,这样format %1就相当于formata:,于是上面的命令运行时实际执行的是format a:

例:C:根目录下一批处理文件名为t.bat,内容为:
@echo off
type %1
type %2

那么运行C:\>t a.txt b.txt
%1 : 表示a.txt
%2 : 表示b.txt
于是上面的命令将顺序地显示a.txt和b.txt文件的内容。

怎么样,使用参数还是比较简单的吧?你这么帅一定学会了^_^.

 

 

 

 

 

三.如何使用组合命令(Compound Command)

1.&

Usage:第一条命令 & 第二条命令 [& 第三条命令...]

用这种方法可以同时执行多条命令,而不管命令是否执行成功

^ 对特殊符号( > < &)的前导字符

 

2.&&

Usage:第一条命令 && 第二条命令 [&& 第三条命令...]

用这种方法可以同时执行多条命令,当碰到执行出错的命令后将不执行后面的命令,如果一直没有出错则一直执行完所有命令;

Sample:在做备份的时候可能会用到这种命令会比较简单,如:
dir file://192.168.0.1/database/backup.mdb && copy file://192.168.0.1/database/backup.mdb E:backup
如果远程服务器上存在backup.mdb文件,就执行copy命令,若不存在该文件则不执行copy命令。这种用法可以替换IF exist了 :)

 

3.||

Usage:第一条命令 || 第二条命令 [||第三条命令...]

用这种方法可以同时执行多条命令,当碰到执行正确的命令后将不执行后面的命令,如果没有出现正确的命令则一直执行完所有命令;

 

 

 

 

 

四、管道命令的使用

1.| 命令
Usage:第一条命令 | 第二条命令 [| 第三条命令...]
将第一条命令的结果作为第二条命令的参数来使用,记得在unix中这种方式很常见。

sample:
time /t>>D:IP.log
netstat -n -p tcp|find ":3389">>D:IP.log
start Explorer
看出来了么?用于终端服务允许我们为用户自定义起始的程序,来实现让用户运行下面这个bat,以获得登录用户的IP。

 

2.>、>>输出重定向命令

重定向操作使用重定向操作符将命令输入和输出数据流从默认位置重定向到其他位置。输入或输出数据流的位置称为句柄。下表列出可用的句柄:

句柄

句柄的数字代号

描述

STDIN

0

键盘输入

STDOUT

1

输出到命令提示符窗口

STDERR

2

错误输出到命令提示符窗口

UNDEFINED

3-9

句柄由应用程序单独定义,它们是各个工具特有的

数字 0 到 9 代表前 10 个句柄。可以使用命令 Cmd.exe 运行程序,并对该程序前 10 个句柄中的任何一个句柄进行重定向。要指定要用的句柄,在重定向操作符之前键入该句柄的数字。如果未定义句柄,则默认的 < 重定向输入操作符是 0,而默认的 > 重定向输出操作符是 1。键入< 或 > 操作符之后,必须指定数据的读写位置。可以指定文件名或其他现有的句柄。要指定重定向到现有句柄,请使用与 (&) 字符,后面接要重定向的句柄号(即 &句柄号)。例如,下面的命令可以将句柄 2(即 STDERR)重定向到句柄 1(即 STDOUT):2>&1


将一条命令或某个程序输出结果的重定向到特定文件中, > 与 >>的区别在于,>会清除调原有文件中的内容后写入指定文件,而>>只会追加内容到指定文件中,而不会改动其中的内容。

sample1:
echo hello world>c:hello.txt (stupid example?)

sample2:

 

3.< 、>& 、<&  (不常用)
< 从文件中而不是从键盘中读入命令输入。
>& 将一个句柄的输出写入到另一个句柄的输入中。
<& 从一个句柄读取输入并将其写入到另一个句柄输出中。

 

 


rmdir /S /Q %mhnet% 2>NUL 1>NUL 做简单解释。这句代码的大意是指将 %mhnet% 指定的目录删除,/s 代表删除其中的子目录, /q 表示删除目录树时不提示确认, 1>nul 表示将正确删除目录树的信息禁止输出,2>nul 表示将删除过程中的错误信息禁止输出。


 

 

 

 

进阶篇

FOR命令详解

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

for语句的基本用法
正如色彩缤纷的七彩光芒是由红绿蓝三原色构成的一样,最复杂的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语句了:
[example]

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

保存为批处理文件并执行,将会在弹出的批处理窗口中看到这样的信息:
bbs.bathome
请按任意键继续...很快地,你会觉得这个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流程。

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

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

和example1的执行结果相比,example2发生了如下变化:

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

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

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

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

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



应该明确的是,for不是一个简单的命令,它的用法比较复杂,它还可以带四个参数(/L /D /R /F),其中:/L和/F参数是最经常用到的。当然,它本身也可以不带参数,下面我们通过具体的例子来讲解for的运用。

一、不带参数的for:

@echo off
for %%i in (1 2 3 4 5) do echo %%i
pause

将以上代码保存为批处理文件(如何保存?),然后运行,可以发现屏幕上显示1 2 3 4 5(每字一行)
是不是明白了一些?它的整个运行机制我们可以这样看:for不停的从括号中拿出5个“东西”来(以空格做间隔),并将这5个“东西”依次传给临时变量%%i,同时把这个变量echo出来....

从这个例子我们可以看出,for的基本用法是:
for 变量 in (目标) do 干什么?

变量常用%%i 来表示,当然也可以换成%%j;目标就是待处理的对象集合,比如这里的1 2 3 4 5;这里的干什么的内容为:批处理命令。

二、带参数 /L 的for (这里的 参数/L 可以理解为 "list" 的意思,代表一个数列)

FOR /L %variableIN (start,step,end) DO command [command-parameters] 该集表示以增量形式从开始到结束的一个数字序列。

 

@echo off
for /l %%i in (1 1 5) do echo %%i
pause

显示结果也为:1 2 3 4 5(每字一行)
它的意思和上面的意思差不多,但是括号中的对象却不需要 写成 1 2 3 45 的形式了,而是:1 1 5,因为它启用了参数 /L ,就是告诉for,这个括号里的对象是个数列,怎样的数列?就是以 1 开始,步长 为1 ,结束值为5的一个等差数列,再举个实例:
::显示 从 10 - 20 的所有偶数:

@echo off
for /l %%i in (10 2 20) do echo %%i
pause

 

三、for的 /D 和/R 参数(这两个参数个人比较少用)
1>/D参数(常用来查询 当前目录 或者 指定目录的文件夹)
基本用法:FOR /D%variable IN (set) DO command [command-parameters]  如果集中包含通配符,则指定与目录名匹配,而不与文件名匹配。
如:查询F盘根目录下的文件夹

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

@echo off
for /d %%i in (f:\*) do echo %%i
pause>nul

如果省略 括号中的 "f:\",则会直接查询 批处理 所在目录的文件夹
假设 本批处理文件 保存在:F:\test下
运行以下批处理代码,将会查询 F:\test下的文件夹
代码:

@echo off
for /d %%i in (*) do echo %%i
pause>nul2>


/r参数
基本用法:FOR /R[[drive:]path] %variable IN (set) DO command [command-parameters]
检查以[drive:]path 为根的目录树中,所有符合(set)的文件或者文件夹。如果在 /R 后没有指定目录,则使用当前目录。如果集仅为一个单点(.)字符,则枚举该目录树。
用法示例:
枚举F:盘下所有的文件
代码:

@echo off
for /r f:\ %%i in (*) do echo %%i
pause>nul

枚举F:盘下所有的 .bat文件(包括子目录),则:
代码:

@echo off
for /r f:\ %%i in (*.bat) do echo %%i
pause>nul

如果省略以上代码中的F:\,则会列举当前目录所有符合(set)的文件
如:列举批处理所在目录的 所有 批处理文件(包括子目录)
代码:

@echo off
for /r %%i in (*.bat) do echo %%i
pause>nul

 

四、带参数 /f 的for(这里的参数/F可以理解为“file”的意思,代码处理对象为文本串)
for /f 参数最为复杂,难懂和常用.
在刚学时确实费了我不少脑筋,下面就我个人的理解,给新手们通俗的讲讲,也好让新手少走些弯路.

 

以默认方式,/F 通过每个文件的每一行中分开的第一个空白符号。跳过空白行。可通过指定可选"options"参数替代默认解析操作。这个带引号的字符串包括一个或多个指定不同解析选项的关键字:

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

for /f"skip=1 tokens=1,2* delims= " %%a in (a.txt) do echo %%a %%b %%c
pause

先从引号内的东西讲起,很多新手对这些难以理解,因为 for /? 翻译的简直是一塌糊涂.
skip=
tokens=
delims=
这三项是用的最多的,根据需要.可以不用,可以一起使用,也可以只使用一个或两个.
但是不管使用几个都要用引号将它们扩起来.当然不使用时,自然就不需要引号了.
skip=
for循环文本内容是以行为单位,从上至下进行的,skip=1意识就是跳过文本的第一行,即不循环第一行
那么skip=2 自然就是跳过前两行了,依次类推.........
delims=
先讲这句
delims=后面的字符的意识是,将文本每一行的内容以delims=后面的字符分割成若干列.
假设a.txt某一行的内容是 111,222.333 444/555
我们用下面的语句

例二:

for /f"tokens=1-5 delims=,./ " %%a in (a.txt) do echo %%a %%b %%c %%d %%e
pause

显示结果是 111 222 333 444 555
 意思就是把111,222.333444/555以,./和空格(不分先后)分成了5列.注意代码中/和"后面有个空格,使用中要注意空格要放到最后,如"delims=,. /" 这样就不行了.那如果我们不使用逗号来分割会如何呢?如: "delims=./ "那么就会分割成111,222 333 444 555  看出区别了吗?delims=后面可以是多个字符,可以是空格,也可以什么都没有,什么都没有代表什么呢?就是不以任何东西为分割符,也是整行的内容了,因为for默认是以,;和空格作分割符的,所以一般要取得整行内容通常会用"delims="这样的形式来取消for的默认分割符。
tokens=
tokens=1-5
1-5很好理解就1至5,前面我们用delims=后面的字符为分割符,将文本内容分成了多列,那么你需要的是哪些列呢?用tokens=可以很好帮你提取到。
还是以例二为例:
通过dilims=,./  将文本分成了111 222333 444 555 五列.
注意代码中前面有个%%a 这里的%%a就是代表第一列,第二列就是%%b,第三列就是%%c 依此类推.....
那么我们如果把echo %%a %%b %%c %%d %%e 改为 echo %%e %%d %%c %%b %%a 会如何呢?
当然.会显示 555 444 333 222 111
如果是:echo %%b%%d 又会显示什么呢?   不用我说了吧!
若是第一个%%a把它改为%%i也是一样,那么第二列就是%%j...%%k...依此类推....
明白了?就是按英文字母的顺序依此类推的.
这里我们用的是tokens=1-5但是在例一中,我们用的是tokens=1,2*有什么区别呢?
其实差不多-号代表从几至几而逗号代表单一的,如 tokens=1,5就是代表第一列和第五列,而不是1至5列.
*号代表剩下的所有的列.如:tokens=1,2*代表%%a为第一列,%%b为第二列,%%c代表后面所有的列.
for /f 不但可以循环文本内容还可以循环字符窜,如:

例三:
代码:

for /f"tokens=1-3 delims=,./ " %%a in ("111,222.333 444/555") doecho %%a %%b %%c
pause

只要将()里的字符串用引号扩起来,for就会把它当字符串来循环,而不是文本.

sample1:
FOR /F "eol=; tokens=2,3* delims=, " %i in (myfile.txt) do command

会分析 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 变量参照的替换已被增强。

 

 

 

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

@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盘和移动硬盘的分区,但是,当光驱中有盘的时候,也会被列出来,这是本代码的一个缺憾,在以后的讲解中,我将向大家讲述如何消除这个瑕疵,敬请关注本系列的后续章节。

 

 

 

 

 

 

命令大全篇


1 echo
@
#关闭单行回显
echo off
#从下一行开始关闭回显
@echo off
#从本行开始关闭回显。一般批处理第一行都是这个
echo on
#从下一行开始打开回显
echo
#显示当前是 echo off 状态还是 echo on 状态
echo.
#输出一个回车换行,空白行
      #(echo, echo; echo+ echo[ echo] echo/ echo\)

2 errorlevel
echo %errorlevel%
每个命令运行结束,可以用这个命令行格式查看返回码
默认值为0,一般命令执行出错会设 errorlevel 1


3 dir
dir
  #显示当前目录中的文件和子目录
dir /a
           #显示当前目录中的文件和子目录,包括隐藏文件和系统文件
dir c: /a:d
#显示 C 盘当前目录中的目录
dir c: /a:-d
#显示 C 盘根目录中的文件
dir c:\ /b/p
#/b只显示文件名,/p分页显示
dir *.exe /s
#显示当前目录和子目录里所有的.exe文件


4 cd
cd\
#进入根目录
cd
#显示当前目录
cd /d d:\sdk
#可以同时更改盘符和目录


5 md
md d:\a\b\c
#如果 d:\a 不存在,将会自动创建中级目录
#
如果命令扩展名被停用,则需要键入 mkdir \a\b\c

6 rd
rd abc
#删除当前目录里的 abc 子目录,要求为空目录
rd /s/q d:\temp
#删除 d:\temp 文件夹及其子文件夹和文件,/q安静模式


7 del
del d:\test.txt
#删除指定文件,不能是隐藏、系统、只读文件
del /q/a/f d:\temp\*.*
删除 d:\temp 文件夹里面的所有文件,包括隐藏、只读、系统文件,不包括子目录
del /q/a/f/s d:\temp\*.*
删除 d:\temp 及子文件夹里面的所有文件,包括隐藏、只读、系统文件,不包括子目录

rd删除文件夹
del删除文件
当文件夹里有文件的时候,可以用rd /s 命令把文件夹和里面的文件一块删掉
而del只能删除文件,不能删除文件夹


8 ren

ren d:\temp tmp #支持对文件夹的重命名


9 cls
清屏


10 type
显示文件内容
type c:\boot.ini
#显示指定文件的内容,程序文件一般会显示乱码
type *.txt
#显示当前目录里所有.txt文件的内容


11 copy
拷贝文件
copy c:\test.txt d:\test.bak
复制 c:\test.txt 文件到 d:\ ,并重命名为 test.bak
copy con test.txt
从屏幕上等待输入,按 Ctrl+Z 结束输入,输入内容存为test.txt文件
con
代表屏幕,prn代表打印机,nul代表空设备
copy 1.txt + 2.txt 3.txt
合并 1.txt 2.txt 的内容,保存为 3.txt 文件
如果不指定 3.txt ,则保存到 1.txt
copy test.txt +
复制文件到自己,实际上是修改了文件日期


12 title
设置cmd窗口的标题
title
新标题          #可以看到cmd窗口的标题栏变了


13 ver
显示系统版本


14 label
vol
设置卷标
vol
#显示卷标
label
#显示卷标,同时提示输入新卷标
label c:system
#设置C盘的卷标为 system


15 pause
暂停命令


16 rem
::
注释命令
注释行不执行操作


17 date
time
日期和时间
date
#显示当前日期,并提示输入新日期,按\"回车\"略过输入
date/t
#只显示当前日期,不提示输入新日期
time
#显示当前时间,并提示输入新时间,按\"回车\"略过输入
time/t
#只显示当前时间,不提示输入新时间


18 goto
:
跳转命令
:label
#行首为:表示该行是标签行,标签行不执行操作
goto label
      #跳转到指定的标签那一行


19 find (
外部命令)
查找命令
find \"abc\" c:\test.txt
c:\test.txt 文件里查找含 abc 字符串的行
如果找不到,将设 errorlevel 返回码为1
find /i “abc” c:\test.txt
查找含 abc 的行,忽略大小写
find /c \"abc\" c:\test.txt
显示含 abc 的行的行数


20 more (
外部命令)
逐屏显示
more c:\test.txt
#逐屏显示 c:\test.txt 的文件内容


21 tree
显示目录结构
tree d:\
#显示D盘的文件目录结构


22 &
顺序执行多条命令,而不管命令是否执行成功


23 &&
顺序执行多条命令,当碰到执行出错的命令后将不执行后面的命令
find \"ok\" c:\test.txt && echo
成功
如果找到了\"ok\"字样,就显示\"成功\",找不到就不显示


24 ||
顺序执行多条命令,当碰到执行正确的命令后将不执行后面的命令
find \"ok\" c:\test.txt || echo
不成功
如果找不到\"ok\"字样,就显示\"不成功\",找到了就不显示

25 |
管道命令
dir *.* /s/a | find /c \".exe\"
管道命令表示先执行 dir 命令,对其输出的结果执行后面的 find 命令
该命令行结果:输出当前文件夹及所有子文件夹里的.exe文件的个数
type c:\test.txt|more
这个和 more c:\test.txt 的效果是一样的


26 >
>>
输出重定向命令
>
清除文件中原有的内容后再写入
>>
追加内容到文件末尾,而不会清除原有的内容
主要将本来显示在屏幕上的内容输出到指定文件中
指定文件如果不存在,则自动生成该文件
type c:\test.txt >prn
屏幕上不显示文件内容,转向输出到打印机
echo hello world>con
在屏幕上显示hello world,实际上所有输出都是默认 >con
copy c:\test.txt f: >nul
拷贝文件,并且不显示\"文件复制成功\"的提示信息,但如果f盘不存在,还是会显示出错信息
copy c:\test.txt f: >nul 2>nul
不显示文件复制成功的提示信息,并且f盘不存在的话,也不显示错误提示信息
echo ^^W ^> ^W>c:\test.txt
生成的文件内容为 ^W > W
^
> 是控制命令,要把它们输出到文件,必须在前面加个 ^ 符号

27 <
从文件中获得输入信息,而不是从屏幕上
一般用于 date time label 等需要等待输入的命令
@echo off
echo 2005-05-01>temp.txt
date del temp.txt
这样就可以不等待输入直接修改当前日期


28 %0 %1 %2 %3 %4 %5 %6 %7 %8 %9 %*
命令行传递给批处理的参数
%0
批处理文件本身
%1
第一个参数
%9
第九个参数
%*
从第一个参数开始的所有参数

批参数(%n)的替代已被增强。您可以使用以下语法:

%~1 - 删除引号(\"),扩充 %1
%~f1 - %1 扩充到一个完全合格的路径名
%~d1 - 仅将 %1 扩充到一个驱动器号
%~p1 - 仅将 %1 扩充到一个路径
%~n1 - 仅将 %1 扩充到一个文件名
%~x1 - 仅将 %1 扩充到一个文件扩展名
%~s1 - 扩充的路径指含有短名
%~a1 - %1 扩充到文件属性
%~t1 - %1 扩充到文件的日期/时间
%~z1 - %1 扩充到文件的大小
%~$PATH : 1 - 查找列在 PATH 环境变量的目录,并将 %1
扩充到找到的第一个完全合格的名称。如果环境
变量名未被定义,或者没有找到文件,此组合键会
扩充到空字符串

可以组合修定符来取得多重结果:

%~dp1 - 只将 %1 扩展到驱动器号和路径
%~nx1 - 只将 %1 扩展到文件名和扩展名
%~dp$PATH:1 - 在列在 PATH 环境变量中的目录里查找 %1
并扩展到找到的第一个文件的驱动器号和路径。
%~ftza1 - %1 扩展到类似 DIR 的输出行。
可以参照 call/? for/? 看出每个参数的含意
echo load \"%%1\" \"%%2\">c:\test.txt
生成的文件内容为 load \"%1\" \"%2\"
批处理文件里,用这个格式把命令行参数输出到文件


29 if
判断命令
if \"%1\"==\"/a\" echo
第一个参数是/a
if /i \"%1\" equ \"/a\" echo
第一个参数是/a
/i
表示不区分大小写,equ == 是一样的,其它运算符参见 if/?
if exist c:\test.bat echo
存在c:\test.bat文件
if not exist c:\windows (
echo 不存在c:\windows文件夹
)
if exist c:\test.bat (
echo 存在c:\test.bat
) else (
echo 不存在c:\test.bat
)


30 setlocal
endlocal
设置命令扩展名延缓环境变量扩充
SETLOCAL ENABLEEXTENSIONS
#启用\"命令扩展名\"
SETLOCAL DISABLEEXTENSIONS
#停用\"命令扩展名\"
SETLOCAL ENABLEDELAYEDEXPANSION
   #启用\"延缓环境变量扩充\"
SETLOCAL DISABLEDELAYEDEXPANSION
#停用\"延缓环境变量扩充\"
ENDLOCAL
#恢复到使用SETLOCAL语句以前的状态
命令扩展名默认为启用
延缓环境变量扩充默认为停用
批处理结束系统会自动恢复默认值
可以修改注册表以禁用\"命令扩展名\",详见 cmd /? 。所以用到\"命令扩展名\"的程
序,建议在开头和结尾加上 SETLOCAL ENABLEEXTENSIONS ENDLOCAL 语句,以确
保程序能在其它系统上正确运行
\"
延缓环境变量扩充\"主要用于 if for 的符合语句,在 set 的说明里有其实用例程


31 set
设置变量
引用变量可在变量名前后加 % ,即 %变量名%
set
#显示目前所有可用的变量,包括系统变量和自定义的变量
echo %SystemDrive%
#显示系统盘盘符。系统变量可以直接引用
set p
#显示所有以p开头的变量,要是一个也没有就设errorlevel=1
set p=aa1bb1aa2bb2
#设置变量p,并赋值为 = 后面的字符串,即aa1bb1aa2bb2
echo %p%
#显示变量p代表的字符串,即aa1bb1aa2bb2
echo %p:~6%
#显示变量p中第6个字符以后的所有字符,即aa2bb2
echo %p:~6,3%
#显示第6个字符以后的3个字符,即aa2
echo %p:~0,3%
#显示前3个字符,即aa1
echo %p:~-2%
#显示最后面的2个字符,即b2
echo %p:~0,-2%
#显示除了最后2个字符以外的其它字符,即aa1bb1aa2b
echo %p:aa=c%
#c替换变量p中所有的aa,即显示c1bb1c2bb2
echo %p:aa=%
#将变量p中的所有aa字符串置换为空,即显示1bb12bb2
echo %p:*bb=c%
#第一个bb及其之前的所有字符被替换为c,即显示c1aa2bb2
set p=%p:*bb=c%
#设置变量p,赋值为 %p:*bb=c% ,即c1aa2bb2
set /a p=39
#设置p为数值型变量,值为39
set /a p=39/10
#支持运算符,有小数时用去尾法,39/10=3.9,去尾得3p=3
set /a p=p/10
# /a 参数时,在 = 后面的变量可以不加%直接引用
set /a p=”1&0″
#”运算,要加引号。其它支持的运算符参见set/?
set p=
#取消p变量
set /p p=
请输入
屏幕上显示请输入,并会将输入的字符串赋值给变量p
注意这条可以用来取代 choice 命令
注意变量在 if for 的复合语句里是一次性全部替换的,如
@echo off
set p=aaa
if %p%==aaa (
echo %p%
set p=bbb
echo %p%
)
结果将显示
aaa
aaa
因为在读取 if 语句时已经将所有 %p% 替换为aaa
这里的\"替换\",在 /? 帮助里就是指\"扩充\"\"环境变量扩充\"
可以启用延缓环境变量扩充,用 ! 来引用变量,即 !变量名!
@echo off
SETLOCAL ENABLEDELAYEDEXPANSION
set p=aaa
if %p%==aaa (
echo %p%
set p=bbb
echo !p!
)
ENDLOCAL
结果将显示
aaa
bbb
还有几个动态变量,运行 set 看不到
%CD%
#代表当前目录的字符串
%DATE%
#当前日期
%TIME%
#当前时间
%RANDOM%
#随机整数,介于0~32767
%ERRORLEVEL%
#当前 ERRORLEVEL
%CMDEXTVERSION%
#当前命令处理器扩展名版本号
%CMDCMDLINE%
#调用命令处理器的原始命令行
可以用echo命令查看每个变量值,如 echo %time%
注意 %time% 精确到毫秒,在批处理需要延时处理时可以用到


32 start
批处理中调用外部程序的命令,否则等外部程序完成后才继续执行剩下的指令


33 call
批处理中调用另外一个批处理的命令,否则剩下的批处理指令将不会被执行
有时有的应用程序用start调用出错的,也可以call调用


34 choice (
外部命令)
选择命令
让用户输入一个字符,从而选择运行不同的命令,返回码errorlevel1234……
win98
里是choice
win2000pro
里没有,可以从win98里拷过来
win2003
里是choice.exe
choice /N /C y /T 5 /D y>nul
延时5


35 assoc
ftype
文件关联
assoc
设置'文件扩展名'关联,关联到'文件类型'
ftype
设置'文件类型'关联,关联到'执行程序和参数'
当你双击一个.txt文件时,windows并不是根据.txt直接判断用 notepad.exe 打开
而是先判断.txt属于 txtfile '文件类型'
再调用 txtfile 关联的命令行 txtfile=%SystemRoot%\system32\NOTEPAD.EXE%1
可以在\"文件夹选项\"\"文件类型\"里修改这2种关联
assoc
#显示所有'文件扩展名'关联
assoc .txt
#显示.txt代表的'文件类型',结果显示 .txt=txtfile
assoc .doc
#显示.doc代表的'文件类型',结果显示 .doc=Word.Document.8
assoc .exe
#显示.exe代表的'文件类型',结果显示 .exe=exefile
ftype
#显示所有'文件类型'关联
ftype exefile
#显示exefile类型关联的命令行,结果显示 exefile=\"%1\" %*
assoc .txt=Word.Document.8
设置.txtword类型的文档,可以看到.txt文件的图标都变了
assoc .txt=txtfile
恢复.txt的正确关联

ftype exefile=\"%1\" %*
恢复 exefile 的正确关联
如果该关联已经被破坏,可以运行 command ,再输入这条命令


36 pushd
popd
切换当前目录
@echo off
c: & cd\ & md mp3
# C:\ 建立 mp3 文件夹
md d:\mp4
# D:\ 建立 mp4 文件夹
cd /d d:\mp4
#更改当前目录为 d:\mp4
pushd c:\mp3
#保存当前目录,并切换当前目录为 c:\mp3
popd
#恢复当前目录为刚才保存的 d:\mp4


37 for
循环命令
这个比较复杂,请对照 for/? 来看
for %%i in (c: d: e: f:) do echo %%i
依次调用小括号里的每个字符串,执行 do 后面的命令
注意%%i,在批处理中 for 语句调用参数用2%
默认的字符串分隔符是\"空格键\"\"Tab\"\"回车键\"
for %%i in (*.txt) do find \"abc\" %%i
对当前目录里所有的txt文件执行 find 命令
for /r . %%i in (*.txt) do find \"abc\" %%i
在当前目录和子目录里所有的.txt文件中搜索包含 abc 字符串的行
for /r . %%i in (.) do echo %%~pni
显示当前目录名和所有子目录名,包括路径,不包括盘符
for /r d:\mp3 %%i in (*.mp3) do echo %%i>>d:\mp3.txt
d:\mp3 及其子目录里的mp3文件的文件名都存到 d:\mp3.txt 里去
for /l %%i in (2,1,8) do echo %%i
生成2345678的一串数字,2是数字序列的开头,8是结尾,1表示每次加1
for /f %%i in ('set') do echo %%i
set 命令的输出结果循环调用,每行一个
for /f \"eol=P\" %%i in ('set') do echo %%i
set 命令的输出结果,忽略以 P 开头的那几行
for /f %%i in (d:\mp3.txt) do echo %%i
显示 d:\mp3.txt 里的每个文件名,每行一个,不支持带空格的名称
for /f \"delims=\" %%i in (d:\mp3.txt) do echo %%i
显示 d:\mp3.txt 里的每个文件名,每行一个,支持带空格的名称
for /f \"skip=5 tokens=4\" %%a in ('dir') do echo %%a
dir 命令的结果,跳过前面5行,余下的每行取第4
每列之间的分隔符为默认的\"空格\"
可以注意到 dir 命令输出的前5行是没有文件名的
for /f \"tokens=1,2,3 delims=- \" %%a in ('date /t') do (
echo %%a
echo %%b
echo %%c
)
date /t 的输出结果,每行取123
第一列对应指定的 %%a ,后面的 %%b %%c 是派生出来的,对应其它列
分隔符指定为 - \"空格\",注意 delims=- 后面有个\"空格\"
其中 tokens=1,2,3 若用 tokens=1-3 替换,效果是一样的
for /f \"tokens=2* delims=- \" %%a in ('date /t') do echo %%b
取第2列给 %%a ,其后的列都给 %%b


38 subst (
外部命令)
映射磁盘。
subst z: \server\d
#这样输入z:就可以访问\server\d
subst z: /d
#取消该映射
subst
  #显示目前所有的映时


39xcopy (
外部命令)
文件拷贝
xcopy d:\mp3 e:\mp3 /s/e/i/y
复制 d:\mp3 文件夹、所有子文件夹和文件到 e:\ ,覆盖已有文件
/i 表示如果 e:\ 没有 mp3 文件夹就自动新建一个,否则会有询问

 

 

以下就是几个常用命令的返回值及其代表的意义:
backup
0
备份成功
1 未找到备份文件
2 文件共享冲突阻止备份完成
3 用户用ctrl-c中止备份
4 由于致命的错误使备份操作中止

diskcomp
0 盘比较相同
1 盘比较不同
2 用户通过ctrl-c中止比较操作
3 由于致命的错误使比较操作中止
4 预置错误中止比较

diskcopy
0 盘拷贝操作成功
1 非致命盘读/写错
2 用户通过ctrl-c结束拷贝操作
3 因致命的处理错误使盘拷贝中止
4 预置错误阻止拷贝操作

format
0 格式化成功
3 用户通过ctrl-c中止格式化处理
4 因致命的处理错误使格式化中止
5 在提示“proceed with format(y/n)?”下用户键入n结束

xcopy
0 成功拷贝文件
1 未找到拷贝文件
2 用户通过ctrl-c中止拷贝操作
4 预置错误阻止文件拷贝操作
5 拷贝过程中写盘错误

 

文档下载地址:

http://download.csdn/download/p876643136/8609677


 

本文标签: 批处理 学习笔记 命令 window