windows脚本-CMD和Batch

一、DOS,CMD和batch

      DOS是磁盘操作系统(英文:Disk Operating System)的缩写,是个人计算机上的一类操作系统。从1981年直到1995年的15年间,DOS在IBM PC兼容机市场中占有举足轻重的地位【1】。

      batch是DOS系统下的脚本,这些脚本是纯文本文档,以.bat为结尾,可以用任何文本编辑器来进行编辑。它的特点是文件的每一行都是当作命令来运行。

      CMD是用来运行batch的程序,在windows上是一个32位的命令行程序,基于windows操作系统的命令解释程序。

二、CMD的常用命令和batch的常用示例

     虽然今天的操作系统已经发展的很好了,但是基于DOS的CMD还是有很大的用途的如在安装java后验证版本,运行java程序,注册表重新注册,设定时间日期,初始化网络连接等。要对CMD进行学习,先了解几个常用的CMD的命令,在windows下面试试效果。

(1)帮助命令 /?

这个比较常用单独说明,遇到不懂的看帮助文档就可以。

命令是:命令+/? 如cd /?会跳出如下界面

windows脚本-CMD和Batch_第1张图片

(2)其它命令

netstat -a:查看所有的端口

tasklist:查看所有的进程

dir(directory):列出当前目录下的文件以及文件夹

md (make directory):创建目录

rd (remove directory): 删除目录(带内容的文件或者文件夹不能直接删除,必须先删除里面,再删除外面)。如果要删除非空目录,可以使用命令

rd /s xxxdir或者rd /s /q xxxdir

cd (change directory) :改变指定目录(进入指定目录)

cd..:退回到上一级目录

cd\:退回到根目录

del (delete): 删除文件,删除一堆后缀名一样的文件*.txt

exit:    退出dos命令行

cls :   (clear screen)清屏

(3)batch文件

batch文件就是一些CMD的命令组合

1. 同时运行多个程序

打开电脑时需要同时运行多个程序,比如打开QQ,浏览器,等

@echo off
echo Starting QQ...
::路径改成自己相应的
start "" "D:\Program Files\QQ\qq.exe"
echo Starting matlab...
start "" "D:\Program Files\MATLAB\R2013a\bing\matlab.exe"
echo Starting Google Talk...
start "" "D:\Program Files\Gtalk\googletalk.exe"

2.批量重命名文件

现有一堆照片,命名格式为0001.jpg,0002.jpg,0003.jpg,…,00020.jpg,……要求在所有文件名前加上A_

@echo off 
rem 启用"延缓环境变量扩充" 
setlocal EnableDelayedExpansion 
set a=1 
rem 循环当前目录下所有图片的文件名,支持带空格的名称 
for /f "delims=" %%i in ('dir /b *.jpg') do ( 
rem 如果没有相同的文件名,则继续 
if not "%%~ni"=="%~n0" ( 
if !a! LSS 10 (ren "%%i" "A_000!a!.jpg") else ren "%%i" "A_!a!.jpg" 
rem 设置数值型变量a=a+1 
set /a a+=1 
) 
) 
echo 批量重命名完成! 
pause

三、batch中常用的一些符号和命令

batch的命令很多但是常用的没多少,所以本文首先介绍batch文件中常见的一些符合和命令,然后介绍bat文件的程序流程控制

1. 常用的一些符合和命令

1.1 @:表示不显示@后面的命令。常用的命令有@echo off,其中echo off表示可以关闭掉整个批处理命令的回显,但不能关掉ECHO OFF这个命令,现在我们在ECHO OFF这个命令前加个@,就可以关掉ECHO OFF这个命令。

这条语句的用处是能让我们更加清楚看到命令的结果,比如在cmd上显示1-5,下面分别展示有@echo off和没有的区别

@echo off

echo %1
::Show 1 to 5
for /l %%i in (1,1,5) do (
    set a=%%i
    echo !a!
    )

pause

windows脚本-CMD和Batch_第2张图片

没有@echo off

windows脚本-CMD和Batch_第3张图片

1.2 %
百分号用在不同的场合,有不同的含义:

① 当百分号成对出现,并且其间包含非特殊字符时,一般做变量引用处理,比如:%var%、%str%。这样引用的目的是,如果不添加%那么解释器就把这个本来是变量的值当成了字符了。

把以下代码保存为批处理文件,运行后观察屏幕显示结果:
   

@echo off
set str=abd
echo var str's value :str
echo var str's value :%str%
pause


在屏幕上将显示这样的结果:

 
   另外,百分号作为变量引用还有一种特殊形式,那就是对形式参数的引用,此时,单个百分号后面紧跟0~9这10个数字,如%0、%1,其中,%0为脚本本身的名称,%1至%9为第二至九个参数...最多支持%0~%9,%10以后就是变量引用了,即%15为%1的值接上5。
请看演示代码:

@echo off 
    if defined str goto next 
    set str= 
    set /p str=请把文件拉到本窗口后回车: 
    call "%~0" %str% 
    pause 
    exit 
    :next 
    cls 
    echo 本批处理文件完整路径为:"%~0" 
    echo 拖到本窗口的文件完整路径为:"%~1" 
    goto :eof

1.3 :、::
① :以:打头的单个的:表示该行是一个标签,它之后的内容是一个标签段,如:test,则表示:test之下的内容是标签段,而test是这个标签段的名,可以用 goto test 、goto :test 跳转到该标签段或用 call :test 调用该子过程;

②:: 而连续两个冒号打头表示该行内容为注释内容,实际上,:: 是个无效的标签名,:加上空格同样可以起到注释的作用,此时,::的功能和注释命令rem相同;但是,rem 注释语句中的某些命令符号如重定向符号和管道符号还是会执行,而如果用::来注释的时候,与::同处一行的所有命令或符号直接被命令解释器忽略掉,无形中提高了注释的兼容性和整个程序的执行效率,并且在众多的命令语句中更显得醒目,所以,注释语句推荐使用::的格式。

1.4 ~
① 用在 set /a 语句中时,它是一元运算符号,表示将操作数字按位取反,例如,set /a num=~1的执行结果是-2,set /a num=~0的结果是-1
② 用在for语句中,表示增强for的功能,能够提取到更多的信息。例如:在批处理文件的for语句中:%%~i表示去掉第一对外侧引号,%%~zi表示获取文件的大小(以字节为单位),%%~ni表示获取文件名,%%~xi表示获取扩展名(带点号)……它们可以组合使用,如%%~nxi表示获取文件名和后缀名。

1.5、>、>>
一般而言,>表示用新内容覆盖原文件内容,>>表示向原文件追加内容,此时,它们以重定向符号的身份出现;

1.6、|
一般而言,它以管道符号的身份出现,表示把在它之前的命令或语句的执行结果作为在它之后的命令或语句的处理对象,简而言之,就是把它之前的输出作为它之后的输入,例如:echo abcd|findstr "b",表示把echo abcd的执行结果,作为findstr "b" 的执行对象,也就是在字符串abcd中查找b字符;如果test.txt中有abcd字符串,则该语句与 findstr "b" test.txt 具有同样的效果;

1.7、^
一般而言,^以转义字符的身份出现。因为在 cmd环境中,有些字符具备特殊功能,如>、>>表示重定向,|表示管道,&、&&、||表示语句连接……它们都有特定的功能,如果需要把它们作为字符输出的话,echo >、echo | ……之类的写法就会出错——cmd解释器会把它们作为具有特殊功能的字符对待,而不会作为普通字符处理,这个时候,就需要对这些特殊字符做转义处理:在每个特殊字符前加上转义字符^,因此,要输出这些特殊字符,就需要用 echo ^>、echo ^|、echo ^|^|、echo ^^……之类的格式来处理;

1.8、&
一般而言,&表示两条命令或语句同时执行的意思。如 echo a&echo b,将在屏幕上同时显示a和b字符。当几条语句含义近似或作用相同且没有先后的顺序之别时,启用&符号连接这些语句将会增加程序的可读性;

1.9、&&、||
这是一对含义截然相反的命令符,&&表示如果它之前的语句成功执行,将执行它之后的语句,而||则表示如果它之前的语句执行失败,将执行它之后的语句;在某些场合,它们能替代 if……else…… 语句;例如: 
 

@echo off 
    md test&&echo 成功创建文件夹test||echo 创建文件夹test失败 
    pause


效果等同于如下代码:

@echo off 
    md test 
    if "%errorlevel%"=="0" (echo 成功创建文件夹test) else echo 创建文件夹test失败 
    pause

 

1.10、+、-、*、/
在 set /a 语句中,这些符号的含义分别为:加、减、乘、除。例如:set /a num=1+2-3*4/5。需要注意的是,这些运算符号遵循数学运算中的优先级顺序:先乘除后加减,有括号的先算括号,并且,直接忽略小数点,因此,刚才那个算式的结果是1而不是0或0.6。
另外,有可能会在代码中看到这样的写法:set /a num+=1、set /a num-=1、set /a num*=1 和 set /a num/=1,这些表示累加、累减、累乘、累除,步长都是1,展开后的完整写法为:set /a num=num+1、set /a num=num-1、set /a num=num*1 和 set /a num=num/1(set /a 语句中,变量引用可以忽略百分号对或感叹号对,set /a num=%num%+1 与 set /a num=num+1 等同)

二、batch的流程控制

2.1 if命令


   IF 条件判断语句,语法格式如下:
IF [NOT] ERRORLEVEL number command
IF [NOT] string1==string2 command
IF [NOT] EXIST filename command

(1) IF [NOT] ERRORLEVEL number command
IF ERRORLEVEL这个句子必须放在某一个命令的后面,执行命令后由IF ERRORLEVEL 来判断命令的返回值。Number的数字取值范围0~255,判断时值的排列顺序应该由大到小。返回的值大于等于指定的值时,条件成立。

例:

@echo off
dir c:
rem退出代码为>=1就跳至标题1处执行,>=0就跳至标题0处执行
IF ERRORLEVEL 1 goto 1
IF ERRORLEVEL 0 goto 0
Rem 上面的两行不可交换位置,否则失败了也显示成功。
:0
echo 命令执行成功!
Rem 程序执行完毕跳至标题exit处退出
goto exit
:1
echo 命令执行失败!
Rem 程序执行完毕跳至标题exit处退出
goto exit
:exit
pause


运行显示:命令执行成功!
(2) IF [NOT] string1==string2 command
string1和string2都为字符的数据,英文内字符的大小写将看作不同,这个条件中的等于号必须是两个(绝对相等的意思)
条件相等后即执行后面的command
检测当前变量的值做出判断,为了防止字符串中含有空格,可用以下格式
if [NOT] {string1}=={string2} command
if [NOT] [string1]==[string2] command
if [NOT] "string1"=="string2" command
这种写法实际上将括号或引号当成字符串的一部分了,只要等号左右两边一致就行了,比如下面的写法就不行:
if {string1}==[string2] command
(3) IF [NOT] EXIST filename command
EXIST filename为文件或目录存在的意思

echo off
IF EXIST autoexec.bat echo 文件存在!
IF not EXIST autoexec.bat echo 文件不存在!

2.2 for 命令

1. 基本格式
FOR %%variable IN (set) DO command [command-parameters]
  %%variable  指定一个单一字母表示可替换的参数。
  (set)            指定一个或一组文件。可以使用通配符。
  command     指定对每个文件执行的命令。
  command-parameters
                   为特定命令指定参数或命令行开关。
参数:FOR有4个参数 /d   /l   /r   /f   下面用例子解释

2. 参数 /d
FOR /D %%variable IN (set) DO command [command-parameters]
    如果集中包含通配符,则指定与目录名匹配,而不与文件
    名匹配。
如果 Set (也就是我上面写的 "相关文件或命令") 包含通配符(* 和 ?),将对与 Set 相匹配的每个目录(而不是指定目录中的文件组)执行指定的 Command。
这个参数主要用于目录搜索,不会搜索文件,看这样的例子

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


运行会把C盘根目录下的全部目录名字打印出来,而文件名字一个也不显示!
在来一个,比如我们要把当前路径下文件夹的名字只有1-3个字母的打出来

@echo off
for /d %%i in (???) do echo %%i
pause


这样的话如果你当前目录下有目录名字只有1-3个字母的,就会显示出来,没有就不显示了
这里解释下*号和?号的作用,*号表示任意N个字符,而?号只表示任意一个字符
知道作用了,给大家个思考题目!

@echo off
for /d %%i in (window?) do echo %%i
pause


保存到C盘下执行,会显示什么呢?自己看吧! 显示:windows
/D参数只能显示当前目录下的目录名字。


3. 参数 /R
FOR /R [[drive:]path] %%variable IN (set) DO command [command-parameters]
    检查以 [drive:]path 为根的目录树,指向每个目录中的
    FOR 语句。如果在 /R 后没有指定目录,则使用当前
目录。如果集仅为一个单点(.)字符,则枚举该目录树。
递归
上面我们知道,/D只能显示当前路径下的目录名字,那么现在这个/R也是和目录有关,他能干嘛呢?放心他比/D强大多了!
他可以把当前或者你指定路径下的文件名字全部读取,注意是文件名字,有什么用看例子!
请注意2点:
    1、set中的文件名如果含有通配符(?或*),则列举/R参数指定的目录及其下面的所用子目录中与set相符合的所有文件,无相符文件的目录则不列举。
    2、相反,如果set中为具体文件名,不含通配符,则枚举该目录树(即列举该目录及其下面的所有子目录),而不管set中的指定文件是否存在。这与前面所说的单点(.)枚举目录树是一个道理,单点代表当前目录,也可视为一个文件。
例:

@echo off
for /r c:\ %%i in (*.exe) do echo %%i
pause


咱们把这个BAT保存到D盘随便哪里然后执行,我会就会看到,他把C盘根目录,和每个目录的子目录下面全部的EXE文件都列出来了

例:

@echo off
for /r %%i in (*.exe) do @echo %%i
pause


参数不一样了吧!这个命令前面没加那个C:\也就是搜索路径,这样他就会以当前目录为搜索路径,比如你这个BAT你把他放在d:\test目录下执行,那么他就会把D:\test目录和他下面的子目录的全部EXE文件列出来!!!
例:

@echo off
for /r c:\ %%i in (boot.ini) do echo %%i
pause


运行本例发现枚举了c盘所有目录,为了只列举boot.ini存在的目录,可改成下面这样:

@echo off
for /r c:\ %%i in (boot.ini) do if exist %%i echo %%i
pause


4. 参数 /L
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)。
使用迭代变量设置起始值 (Start#),然后逐步执行一组范围的值,直到该值超过所设置的终止值 (End#)。/L 将通过对 Start# 与 End# 进行比较来执行迭代变量。如果 Start# 小于 End#,就会执行该命令。如果迭代变量超过 End#,则命令解释程序退出此循环。还可以使用负的 Step# 以递减数值的方式逐步执行此范围内的值。例如,(1,1,5) 生成序列 1 2 3 4 5,而 (5,-1,1) 则生成序列 (5 4 3 2 1)。语法是:

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

保存执行看效果,他会打印从1 2 3 4 5  这样5个数字

更加详细的信息参考文献【3】,这里只对流程控制有个基本的了解就可以了。

三、设置变量等

3.1 set

1. 设置自定义变量

代码如下:

@echo off
set var=我是值
echo %var%
pause

2. 设置自定义变量,并接受用户输入作为值

代码如下:

@echo off
@echo off
set /p var=请输入变量的值:
if %var% == 1 echo 您输入了 1 ~_~
pause

3. SET /A expression
set的/A参数就是让SET可以支持数学符号进行加减等一些数学运算! 支持的数学运算包含(优先权递减):

() - 分组
! ~ - - 一元运算符
* / % - 算数运算符
+ - - 算数运算符
<< >> - 逻辑移位
& - 按位“与”
^ - 按位“异”
| - 按位“或”
= *= /= %= += -= - 赋值
&= ^= |= <<= >>=
, - 表达式分隔符

Batch代码

代码如下:

set /a var=2 - 1 结果是多少呢?如果你看不到结果就echo %var%.....
set /a var=2 * 2 乘法运算
set /a var=2 / 2 除法运算
set /a var=(1+1) + (1+1) 结果等于4 看得懂吧!
set /a a=1+1,b=2+1,c=3+1 运行后会显示一个4,但我们用
echo %a% %b% %c%后看结果,会发现其他数学运算也有效果!,这就是"斗"号的作用!

有时候我们需要直接在原变量进行加减操作就可以用这种语法
set /a var+=1 这样的语法对应原始语法就是set /a var = %var% + 1
都是一样的结果。
对于"逻辑或取余操作符",需要把他们用双引号引起来,看例子
Batch代码

代码如下:

set /a var= 1 "&" 1 这样结果就显示出来了,其他逻辑或取余操作符用法
set /a var= 1 "+" 1 异运算
set /a var= 1 "%" 1 取模运算
set /a var= 2 "<<" 2 次方运算
set /a var= 4 ">>" 2 这个不太记得数学里的叫法....

 

4. 替换变量值的内容
语法:set newVar="oldVar:str1=str2%
将变量oldVar的值中的str1替换成str2,并将替换后的变量值赋给newVar.
看例子

代码如下:

@echo off
set a=bbs.verybat.cn
echo 替换前的值: "%a%"
set var=%a:bbs=sss%
echo 替换后的值: "%var%"
pause

对比一下,我们发现他把变量%a%的bbs给替换掉了,换成了sss.
5.字符串截取
1、%Var:~start,len%
注意:从0开始。
例如:

代码如下:

@echo off
set a=www.jb51.net
set var=%a:~1,2%
echo %var%
pause

输出结果是:ww

2、%Var:~-len%
截取倒数len位
3、%Var:~0,-len%
截取从第一位开始,倒数第len位结束的值。
例子

代码如下:

@echo off
set a=www.jb51.net
set var=%a:~0,-3%
echo %var%
pause

 

四、例子

下面是自己写的例子,对batch有了了解之后,就实现一个小任务。

学校里可以通过代理来共享网络,只要某台电脑联网并开启了CCPROXY,那么只要知道这一台电脑的IP地址,那么就能够实现免费上网。

这个任务包含两个方面

1.需要知道局域网中哪台电脑连入了了。

这个可以通过ping这条命令来实现。根据计算机网络知识知道,学校里的局域网的地址范围是172.16.0.0.-172.31.255.255.

那么写个bat文件遍历所有IP地址,把那些能够ping通的保存下来就可以了。

2.如何测试ping通的电脑开启了ccproxy。

可以通过proxifier这个软件来测试,但是存在问题是测试比较麻烦,需要配置和check。暂时还没能写个脚本。

先解决第一个问题

@echo off
setlocal enabledelayedexpansion
for /l %%a in (16,1,31) do (
   for /l %%b in (0,1,255) do (
      for /l %%c in (0,1,255) do (
           ping 172.%%a.%%b.%%c -n 2 -w 100
           if not !errorlevel!==0 (
           ::    >>"test_block.txt" echo IP:172.%%a.%%b.%%c  cannot ping )
           if not !errorlevel!==1 (
               >>"test_passing.txt" echo IP:172.%%a.%%b.%%c  can ping )
           )
       )
)
echo test finished !
pause

程序比较简单,3层循环,按照IP地址范围测试,测试成功到保存的test_passing.txt文件中。虽然设置了回显请求数位2,并且等待超时时间为100ms,但是还是运行很久,可以进一步减少IP地址范围,如一个实验室内。

 

 

参考文献

【1】:http://zh.wikipedia.org/wiki/DOS

【2】:http://www.jb51.net/list/list_106_1.htm

【3】:http://www.cnblogs.com/glaivelee/archive/2009/10/07/1578737.html

转载于:https://www.cnblogs.com/dawnminghuang/p/4401669.html

你可能感兴趣的:(windows脚本-CMD和Batch)