Board logo

标题: [原创] 批处理实用技术 [打印本页]

作者: batman    时间: 2008-6-21 11:51     标题: 批处理实用技术

一、[cmd所能处理的最大值和最小值]
       在cmd中和批处理中对数值的处理存在着上下限,下面这段代码将告诉你这个上下限分别是多少,大家以后在遇到超过此上下限的数值处理问题时就要注意并另想办法了(代码原作者就是本版版主随风):
  1. @echo off
  2. set /a d=1^<^<31,x="~d"
  3. echo cmd所能处理的最小数值为 %d%
  4. echo cmd所能处理的最大数值为 %x%
  5. pause>nul
复制代码
二、[批处理在人机对话中如何限制输出格式和内容]
       在批处理中常常要实现人机对话,由操作者输入相应的内容再进行程序处理(如:菜单选择),那么如何让操作者严格按规定的格式进行输出,注意当程序要求有要求时,才进行限制,不然输入方式越灵活才越实用。下面我写的这段代码是从输入数字个数(3个),数值合法性(十进制),数字输入格式(数字间用空格格开)上来进行限制的:
  1. @echo off&color 1f&mode con cols=60 lines=10
  2. title 限定输入格式批处理 by cn-dos zw19750516
  3. :begin
  4. cls&echo.&echo.&echo     请输入三个十进制数字,中间请用空格格开。
  5. set a=&echo.&set /p a=    请在此处输入数字:
  6. echo %a: =%|findstr "[^0-9]"&&goto wrong
  7. for %%i in (%a%) do set str=%%i&call:lp
  8. if %n% neq 3 set n=0&goto wrong
  9. cls&echo.&echo.&echo     你所输入的三个数值字为:%a% 均为合法的十进制数值。
  10. echo.&echo     继续测试请按任意键,退出请关闭窗口。
  11. pause>nul&goto begin
  12. :lp
  13. set /a n+=1
  14. if "%str:~,1%" equ "0" if "%str:~1%" neq "" set n=0&goto wrong
  15. goto :eof
  16. :wrong
  17. cls&echo.&echo.&echo     输入的数值不是合法的十进制数值,或数值不为三个。&ping /n 2 127.1>nul&goto begin
复制代码
三、[批处理中数值的处理方法]
我们在批处理中经常要遇到数字(值)的处理,下面我就简单讲一下批处理中数字(值)处理方法:
1、随机数
  在系统变量中有一个随机取值的变量%random%,其为0-32767之间的十进制数字,利用这个变量我们就能取得我们想要的任一组随机数字(等下会说明方法)。
2、四则运算
  如我们要对一个变量(数值)进行运算,则可使用set /a命令,如:set /a str+=1就是把变量str的数值加上1,同样只要把这个命令中的+改成-、*、/就可以完成对该数值的减1、乘1、除1运算了,而更重要的是我们可以通过set /a命令来进行四则运算,如:set /a str=5*6+4*3-2*7,也可以进行变量和变量间的四则运算,如:set /a str=%a%/%b%*%c%-%d%,但要注意一点:运算仅限于整数,如要对小数进行运算可先乘上10的n次方。
3、取余
  所谓余数就是除数除以被除数剩下的值,在批处理中取余运算符是用%%来表示的,如:%random%%%56就是把不断地把随机数除以56取余数,得到的数值一定是处在0-55间的,那么我们只要set /a a=%random%%%56就能把变量a的值设定在0-55间(大家想一下为什么a不会等于56),如要把a设定在1-56间,则只需set /a a=%random%%%56+1,我们了解了这点是很重要的,如要随机设定一台机器的ip(假设4个数值都随机取定)则只需写下以下代码(设置部分略去):
  1. @echo off
  2. set /a a=%random%%%256,b=%random%%%256,c=%random%%%256,d=%random%%%256
  3. set ip=%a%.%b%.%c%.%d%
  4. netsh interface...
复制代码
4、去零
  数值去零一般是运用在时间计算上,因时间显示一般都是两位不足两位的自动在个位前补零,如07:04:01,这就给我们在运算中带来麻烦,所以对时间进行运算应该先去零,方法其实也很简单,就是利用取余运算,如要对08去零则只在08前面加上10变成108再不断地除以10余数肯定是8,如时间变量a(值为08)的运算公式为:set /a a=10%a%%%10,但时间是有两位数的,因此要将上面的公式变为set /a a=100%a%%%100,现在我们对上面的07:04:01进行取零,代码如下:
  1. @echo off
  2. set str=07:04:01
  3. for /f "delims=: tokens=1-3" %%a in ("%str%") do (
  4.     set /a a=100%%a%%100,b=100%%b%%100,c=100%%c%%100
  5. )
  6. echo %a%:%b%:%c%&pause>nul
复制代码
最后显示的结果就是7:4:1。
5、递加(减、乘、除)运算
  在批处理中我们经常要用到递加(减、乘、除)的运算,那怎么实现呢?只有通过循环来实现,有两种循环的方法:一种是for循环,一种是goto循环。如我们要对一个数值5进行递加100次变成105,两种方法的代码如下:
     for循环
  1. @echo off
  2. set n=5
  3. for /l %%i in (1,1,100) do set /a n+=1
  4. echo %n%&pause>nul
复制代码
goto循环
  1. @echo off
  2. set n=5
  3. :begin
  4. set /a n+=1
  5. if %n% neq 105 goto begin
  6. echo %n%&pause>nul
复制代码
同理可实现递减、乘、除和重复四则运算。
四、[IF“镶嵌语句实例]
       同FOR一样IF也存在镶嵌语句,下面这段网络拼测命令就是利用的IF的镶嵌(注:192.168.1.1是网关IP地址,192.168.1.8是本机IP地址)来完成的:
  1. @echo off
  2. ping /n 1 www.cn-dos.net >nul
  3. if errorlevel 1 (
  4.    ping /n 1 192.168.1.1 >nul
  5.    if errorlevel 1 (
  6.       ping /n 1 192.168.1.8 >nul
  7.       if errorlevel 1 (
  8.          echo 网卡不通,请检查网卡
  9.          ) else (
  10.          echo 网卡正常,网关不通,请检查网关
  11.   )
  12.        ) else (
  13.        echo 网卡正常,网关通畅,请检查外网连接
  14.     )
  15.     ) else (
  16.     echo 网络通畅
  17. )
  18. pause>nul
复制代码
这段命令是对外网、网关、本机网卡依次进行拼测,然后根据拼测结果来判断网络状况并输出显示。由于拼测网卡、网关中、外网中存在三个拼的返回值(注:当拼不通时,errorlevel为1而拼通时errorlevel为0),为了判断网络终究是在哪个环节中断的,也就是返回值1是在什么环节出现的,而利用了”IF“的镶嵌语句来起到多次判断的作用。
五、[利用数字变量来提取文本内容]
       批处理经常要对文本的内容进行提取,我下面的这段代码就是一个利用数字变量来提取文本内容的示例:
test.txt内容如下:
  1. ALLUSERSPROFILE=C:\Documents and Settings\All Users
  2. APPDATA=C:\Documents and Settings\Administrator\Application Data
  3. CLIENTNAME=Console
  4. CommonProgramFiles=C:\Program Files\Common Files
  5. COMPUTERNAME=A8E5C30E80494F9
  6. ComSpec=C:\WINDOWS\system32\cmd.exe
  7. FP_NO_HOST_CHECK=NO
  8. HOMEDRIVE=C:
  9. HOMEPATH=\Documents and Settings\Administrator
  10. LOGONSERVER=\\A8E5C30E80494F9
  11. NUMBER_OF_PROCESSORS=1
  12. OS=Windows_NT
  13. Path=C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem
  14. PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH
  15. PROCESSOR_ARCHITECTURE=x86
  16. PROCESSOR_IDENTIFIER=x86 Family 15 Model 2 Stepping 9, GenuineIntel
  17. PROCESSOR_LEVEL=15
  18. PROCESSOR_REVISION=0209
  19. ProgramFiles=C:\Program Files
  20. PROMPT=$P$G
  21. SESSIONNAME=Console
  22. SystemDrive=C:
  23. SystemRoot=C:\WINDOWS
  24. TEMP=C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp
  25. TMP=C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp
  26. USERDOMAIN=A8E5C30E80494F9
  27. USERNAME=Administrator
  28. USERPROFILE=C:\Documents and Settings\Administrator
  29. windir=C:\WINDOWS
复制代码
我们通过下面的代码就可以做到对文本任一行内容的提取
  1. @echo off&setlocal enabledelayedexpansion
  2. for /f "delims==" %%i in (test.txt) do (
  3.     set /a n+=1
  4.     set _!n!=%%i
  5. )
  6. set /p a=请输入要提取的行数:
  7. cls&echo 你所提取的行为:!_%a%!
  8. pause>nul
复制代码
六、[让批处理记录历史运行次数]
      在有些时候,我们需要知道程序被运行了多少次(当然是在特殊情况下),这就要求批处理运行一次手自动记录自己所运行的次数,据本人所知要实现这一目的有两个简单的方法,下面一一述之:
      第一种方法借助文本文件记录自己的运行次数,就是批处理在运行时先读取文本上所记录的数值(就是上一次运行的数值,原始值可设为0),然后将数值加1再输入替换掉文本中原来的数值,代码示例如下(文本名称为num.txt)
  1. @echo off
  2. if not exist num.txt echo 0>num.txt
  3. set /p num=<num.txt
  4. if %num% neq 0 echo.&echo 程序已经运行了%num%次
  5. set /a num+=1
  6. echo.&echo 这是第%num%次运行
  7. echo %num%>num.txt
  8. pause>nul
复制代码
第二种方法是批处理自身记录并更新运行次数,也就是运行一次改写一次自身代码,代码示例如下:
  1. ::0
  2. @echo off&setlocal enabledelayedexpansion
  3. for /f "delims=:" %%i in (%~fs0) do set num=%%i&goto next
  4. :next
  5. if %num% neq 0 echo.&echo 程序已经运行了%num%次
  6. set /a num+=1
  7. echo.&echo 这是第%num%次运行
  8. for /f "delims=" %%i in ('type %~fs0') do (
  9.      if not defined flag (
  10.      set flag=A&echo ::%num%>%~fs0
  11.      ) else (
  12.      echo %%i>>%~fs0
  13.      )
  14. )
  15. pause>nul
复制代码
七、[谈谈截取字符命令]
       在批处理中截取字符是一个经常用到又很实用的命令,特别是在处理文本字符时尤其重要,因此,新手一定要熟悉和掌握截取字符命令,下面我就来谈一谈字符截取命令:
       1、什么叫字符截取?
        所谓字符截取就是从目标字符串(可以是数字、汉字、字母、符号,也可以是四者的任意组合)中提取需要的某一个或某一段字符,其实大家可以把它理解为对一字符串的局部复制,如以下代码示例:
  1. @echo off
  2. set str=www.bbs.bathom.cn
  3. echo 提取字符串%str%中第四个字符后所有字符的命令为:%%str:~4%%,提取的字符为:%str:~4%
  4. echo 提取字符串%str%中最后三个字符前所有字符的命令为: %%str:~,-3%%,提取的字符为:%str:~,-3%
  5. pause>nul
复制代码
2、为什么要截取字符?
         其实只要大家弄明白了我以上所说的,就知道为什么在批处理中要用到字符截取命令了,我也就不再罗嗦,只是以下面的代码示例来加以说明:
  1. @echo off
  2. rem 此代码可以获取本机计算机名(不含多余信息)
  3. for /f "tokens=2 delims=:" %%i in ('ipconfig /all^|findstr "Host Name"') do set str=%%i
  4. echo 截取前获得的本机计算机名为:%str%(前面多了个空格)
  5. echo 运用字符截取命令:%%str:~1%%
  6. echo 截取后获得的本机计算机名为:%str:~1%
  7. pause>nul
复制代码
3、如何进行字符截取?
        字符截取命令形式为%a:~b,c%,其中a表示字串符,b为可正可负可为0的整数,c为可负可正的整数。当b为负数时表示截取时丢弃(或忽略)a字符串中除了后面b个字符的所有字符,当b为0和正数时表示截取时丢弃a字符串中b位前(含b位)的所有字符,当c为负数时表示截取时丢弃a字符串后面c个字符,当c为正数时表示截取时从提取的第一个字符(具体由a定)向后c位后的所有字符。
    注意当b,c都为负数时,|b|应大于|c|。
  再举例如下:
  如 a=123456789
    截取命令    提取的字符        错误所在
    %a:~-2,0%         无                    c不能为0
  %a:~0,0%          无        c不能为0
    %a:~4,0%          无                    c不能为0             
  %a:~-3,-4%    无                    |b|<|c|
    %a:~-2%(无c)  89
    %a:~2%(无c)   3456789
    %a:~,2%(无b)  12
    %a:~,-2%(无b)     1234567
    %a:~-60,2%         12
    %a:~-60,80%        123456789  
    %a:~-6,-2%          4567
    %a:~0,-4%     12345
    %a:~0,4%            1234
  %a:~3,-2%     4567
    %a:~2,5%            34567
    %a:~2,40%    3456789
    4、为新手写了个字符截取练习工具,代码如下:
  1. @echo off&color 1f&mode con cols=90 lines=12
  2. :begin
  3. set tu=★★★★★★★★★★★★★★★■■■■■■■■■■■■■■■
  4. cls&echo.&echo  原始图案为:%tu%
  5. echo.&echo  注意前面有15个五角星后面有15个方块,等下截取后记得数一下。
  6. echo.&echo  命令形式为:%%tu:~2,1%%,其中的2为第一个参数可负可正可为零,1为第二个参数可负可正不为零。
  7. echo.&echo  为了方便重复练习没有设置退出,要退出请直接关闭窗口。
  8. echo.&echo  请按任意键开始练习。&pause>nul
  9. set a=&set b=&set "c="
  10. cls&echo.&set /p a= 请输入第一个参数(应为小于30的整数):
  11. echo %a:-=%|findstr "[^0-9]"&&goto wrong
  12. if "%a%" equ "" goto wrong
  13. if %a% geq 30 goto wrong
  14. cls&echo.&set /p b= 请输入第二个参数(应为大于-30并不为零的整数):
  15. echo %b:-=%|findstr "[^0-9]"&&goto wrong
  16. if "%b%" equ "" goto wrong
  17. if %b% equ 0 goto wrong
  18. if %b% lss -30 goto wrong
  19. set /a c=30-a+b
  20. if %a% gtr 0 if %b% lss 0 if %c% leq 0 goto wrong
  21. cls&echo.&echo  原始图案为:%tu%
  22. echo.&echo  你输入的截取命令是: %%tu:~%a%,%b%%%
  23. echo.&call,echo  截取到的图案是 :%%tu:~%a%,%b%%%
  24. echo.&echo  请按任意键再次练习。&pause>nul&goto begin
  25. :wrong
  26. cls&echo.&echo  输入不合要求,请正确输入。&ping /n 2 127.1 >nul&goto begin
复制代码

[ 本帖最后由 zw19750516 于 2008-6-21 20:50 编辑 ]
作者: namejm    时间: 2008-6-21 13:49

  有个小小的错误,其实 set /a num=a+b+c 也是可以的,变量 a、b、c 也可以不用双百分号引用。
作者: batman    时间: 2008-6-21 14:10

原帖由 namejm 于 2008-6-21 13:49 发表
  有个小小的错误,其实 set /a num=a+b+c 也是可以的,变量 a、b、c 也可以不用双百分号引用。

谢谢指正,已经修改了。
作者: zhouyongjun    时间: 2008-11-20 09:27

好贴,支持,受益匪浅。
作者: computerarts    时间: 2008-11-20 10:16

很不错,我批处理这方面很菜,多谢楼主。
作者: wxcute    时间: 2008-11-20 10:27     标题: 好帖,支持

其实用 % 符号括起来也挺有用的

set num1=a+b+c
set num2=%a%+%b%+%c%
set /a num3=%num2%

num1 显示的是变量公式;
num2 可显示带入值的式子;
num3 就是结果了。
作者: 小勇12    时间: 2008-11-20 20:25

经典呀  可以哟!!!!
作者: luchina00    时间: 2008-11-20 23:32     标题: 顶你...

我比较菜,虽然看得不是很明白,不过我知道是好东西,先收起来啦,有空再慢慢研究.
作者: ljl    时间: 2008-11-27 14:07

高手啊我一定要学会这个谢天谢地谢楼主了^_^
作者: xss    时间: 2011-8-18 20:47

在“批处理在人机对话中如何限制输出格式和内容”一节中的代码段中有一句代码如下:
echo %a: =%|findstr "[^0-9]"&&goto wrong
不知在%a:的冒号:是啥意思,还望大侠指教,不胜感激!
作者: PCL505512957    时间: 2011-8-21 00:23

  1. findstr "[^0-9]
复制代码
这个代码,神马意思啊
作者: cjiabing    时间: 2011-8-21 00:27

回复 10# xss


    貌似替换后搜索
作者: cjiabing    时间: 2011-8-21 00:28

回复 11# PCL505512957


    搜索纯数字。或者,判断是不是0到9这些数字。
作者: PCL505512957    时间: 2011-8-21 22:43

回复 13# cjiabing


    哦,谢谢




欢迎光临 批处理之家 (http://www.bathome.net/) Powered by Discuz! 7.2