最近工作中需要使用批来处理一些事情,之前没用过bat,对批也是一点不了解,于是就找度娘,现记录学习过程,打好基础,错误、不当之处欢迎指正,本文持续更新ing:


eg、command1 & command2 & command3......

无论成功与否,每条命令均会执行

&&

eg、command1 && command2 && command3......

遇到错误后续命令不再执行

||

eg、command1 || command2 || command3......

遇到成功执行命令则后续命令不再执行

|

eg、command1 | command2 | command3......

将前一个命令执行的结果做为后面一个命令的参数,同linux中|

1 > null 

不显示命令运行的正确提示

2 > null

不显示命令运行的错误提示

 > null

屏蔽命令输出内容  

echo表示显示此命令后的字符,例如echo hello,echo.表示一行空行,点和echo中间没空格 

echo off 表示在此语句后所有运行的命令都不显示命令行本身  

@与echo off相象,但它是加在每个命令行的最前面,表示运行时不显示这一行的命令行(只能影响当前行)。  

eg、重新创建映射

@echo off
net use M: /del /yes
net use M: \\192.168.100.163\file 123456 /user:administrator

重新创建映射,M:盘符;/yes:交互模式默认设置;123456:密码;administrator:用户名

call调用另一个批处理文件(如果不用call而直接调用别的批处理文件,那么执行完那个批处理文件后将无法返回当前文件并执行当前文件的后续命令)。    

pause 运行此句会暂停批处理的执行并在屏幕上显示“Press any key to continue...”或“请按任意键继续。。。”的提示,等待用户按任意键后继续。  

rem表示此命令后的字符为解释行(注释)(小技巧:用::代替rem),不执行,只是给自己今后参考用的(相当于程序中的注释)。在echo on状态rem注释的行会回显,而::不会回显  

    任何以冒号:开头的字符行, 在批处理中都被视作标号, 而直接忽略其后的所有内容。而标号分为有效和无效两种。
    有效标号:冒号后紧跟一个以字母数字开头的字符串,goto语句可以识别。
    无效标号:冒号后紧跟一个非字母数字的一个特殊符号,goto无法识别的标号。

    无效可以起到注释作用,所以 :: 常被用作注释符号,其实 :+ 也可起注释作用。

参数表示符“%”

参数是指在运行批处理文件时在文件名后加的以空格(或者Tab)为分隔的字符串。

%[1-9]表示参数变量可以从%0到%9,%0表示批处理命令本身,其它参数字符串用%1到%9顺序表示。

d:根目录下有一批处理文件名为t.bat,内容为:

@echo off
dir %1
type %2

在DOS下执行D:\>t d: 1.txt相当于dir d: 和type 1.txt

title 设置cmd窗口的标题

设置cmd窗口的标题,批处理编程常用。
title 新标题        #可以看到cmd窗口的标题栏变了

if 是条件语句 用来判断是否符合规定的条件,从而决定执行不同的命令。

1、if [not] "参数" == "字符串" 待执行的命令  

  参数如果等于(not表示不等,下同)指定的字符串,则条件成立,运行命令,否则运行下一句

@echo off
if "%1"=="a" echo %1=a

2、if [not] exist [路径\]文件名 待执行的命令  

  如果有指定的文件,则条件成立,运行命令,否则运行下一句。

@echo off
if exist d:\2.txt type d:\2.txt
  echo 2.txt is not exist

3、if errorlevel <数字> 待执行的命令  

  DOS程序在运行结束后会返回一个数字值用来表示程序运行的结果(或者状态),通过if errorlevel命令可以判断程序的返回值,根据不同的返回值来决定执行不同的命令(返回值必须按照从大到小的顺序排列)。如果返回值等于指定的数字,则条件成立,运行命令,否则运行下一句

@echo off
netstat -ano|findstr "Zabbix Agent"
if ERRORLEVEL 1  (net stop "Zabbix Agent" & net start "Zabbix Agent" && echo Zabbix Agent已启动) else (echo "Zabbix Agent" is running)

获取返回值,以ping命令为例:先Ping一个可以ping通的地址,然后运行echo %errorlevel%查看此时的返回值,再ping一个不存在的地址,再运行echo %errorlevel%查看返回值

4、goto批处理文件运行到这里将跳到goto所指定的标号处(标号即label,标号用:后跟标准字符串来定义),goto语句一般与if配合使用,根据不同的条件来执行不同的命令组。

@echo off
:again
:netstat -ano|findstr "Zabbix Agent"
:if ERRORLEVEL 1  (net stop "Zabbix Agent" & net start "Zabbix Agent" && echo Zabbix Agent已启动) else (echo "Zabbix Agent" is running)
ping -n 10 10.15.98.190 >nul
goto again

5、bat命令运行时候,怎么才能不显示那个cmd的窗口

新建一个记事本,里面输入:

createobject("wscript.shell").run "D:\ftp_2_192\行情文件传输.bat",0

其中 createobject("wscript.shell").run 为固定语句,后面紧跟批处理文件所在的径路和文件名,另外最后再跟一个参数0,就可以达到隐藏的效果。然后把这个记事本保存为后缀名为.vbs的文件,到时候你只要运行这个vbs文件就达到目的了!~


6、ftp通过bat实现自动上传

C:\Users\Administrator>file ftp2-192.bat
@echo off
Title 10.10.2.192行情文件同步程序,请勿关闭!
:again
set date1=%date:~5,2%%date:~8,2%
echo open 222.73.4.193>%cd%\hqfile.txt
echo hqfile112>>%cd%\hqfile.txt
echo Finchina*csdp>>%cd%\hqfile.txt
echo cd mktdt00>>%cd%\hqfile.txt
echo put r:\file\mktdt00.txt >> %cd%\hqfile.txt
echo cd ../SHFILE>>%cd%\hqfile.txt
echo put R:\SHFILE\cpxx%date1%.txt>>%cd%\hqfile.txt
echo cd ../SHHQ>>%cd%\hqfile.txt
echo put R:\SHHQ\mktdt01.txt>>%cd%\hqfile.txt
echo bye>>%cd%\hqfile.txt
ftp -s:%cd%\hqfile.txt
echo %Date:~0,4%-%Date:~5,2%-%Date:~8,2% %Time:~0,2%:%Time:~3,2%:%Time:~6,2%更新完成,20s后更再新......
del %cd%\hqfile.txt /q
ping -n 20 127.0.0.1 >nul
goto again

forfiles  从文件夹中选择要处理的文件

格式:forfiles /p <目标目录名> [/s] /d <天数> /c <执行的命令> 

/p 指定了要在哪个目录里查找文件,默认是当前工作目录。

/s 包括子目录 

/d 指定一个日期或天数,用于比较文件的最后修改日期是否符合条件。有绝对日期和相对日期, 例如:"/d -7"指当前日期的7天前;"/d -2014/12/15"这样所有早于2014年12月15日的文件。注意指定的时间是""yyyy/MM/dd"的格式。 其上一次修改日期大于或等于 (+),小于或等于 (-)

/c 对每个找到的文件执行的命令。命令字符串应该用双引号括起来。默认命令是 "cmd /c echo @file"。

    下列变量可以用在命令字符串中:
         @file    - 返回文件名。
         @fname   - 返回不带扩展名的文件名。
         @ext     - 只返回文件的扩展。
         @path    - 返回文件的完整路径。
         @relpath - 返回文件的相对路径。
         @isdir   - 如果文件类型是目录,返回 "TRUE"; 如果是文件,返回 "FALSE"。
         @fsize   - 以字节为单位返回文件大小。
         @fdate   - 返回文件上一次修改的日期。
         @ftime   - 返回文件上一次修改的时间。

eg、1、查找D盘下批处理文件

C:\Users\Administrator>forfiles /p d:\ /s /m *.bat /c "cmd  /c echo @file"
"t.bat"
"z.BAT"
C:\Users\Administrator>

2、删除D盘下txt文件

C:\Users\Administrator>forfiles /p d:\  /m *.txt /c "cmd  /c del /q /f  @file"
C:\Users\Administrator>

在例子中使用/Q 和 /F标签来作为删除命令。这意味着这个命令将使用安静模式(/Q)甚至删除只能读的文件(/F)。

3、删除D盘forfiles目录及其子目录下txt文件

C:\Users\Administrator>forfiles/p d:\forfiles /s  /d -7 /m *.txt /c "cmd /c del @file /f"
C:\Users\Administrator>forfiles/p d:\forfiles /s  /d -5 /m *.txt /c "cmd /c del @path"
C:\Users\Administrator>

4、列出D盘下forfiles下14号以后修改过的文件,并列出修改时间

C:\Users\Administrator>forfiles /p d:\forfiles /s /m *.* /d +2014/12/15 /c "cmd /c echo @file The last modified time is @fdate @ftime @fsize"
"bat1.bat" The last modified time is 2014/12/15 17:26:39 0
"dir1_file2.txt" The last modified time is 2014/12/16 10:48:31 15
C:\Users\Administrator>

5、检测当天文件是否存在,并打印最后修改时间

@echo off
forfiles /p U:\%Date:~0,4%%Date:~5,2%%Date:~8,2% /s /m XX.dbf /c "cmd /c echo @file @ftime"
forfiles /p U:\%Date:~0,4%%Date:~5,2%%Date:~8,2% /s /m PAR_QY_INFO%Date:~0,4%%Date:~5,2%%Date:~8,2%.dbf /c "cmd /c echo @file @ftime"
forfiles /p U:\%Date:~0,4%%Date:~5,2%%Date:~8,2% /s /m PAR_JTGPZF%Date:~0,4%%Date:~5,2%%Date:~8,2%.dbf /c "cmd /c echo @file @ftime"
forfiles /p U:\%Date:~0,4%%Date:~5,2%%Date:~8,2% /s /m PAR_PISTOCK_INFO%Date:~0,4%%Date:~5,2%%Date:~8,2%.dbf /c "cmd /c echo @file @ftime"


%date:~0,4%  表示从左向右指针向右偏0位,然后从指针偏移到的位置开始提取4位字符,结果是2014(年的值)

%date:~5,2%  表示指针从左向右偏移5位,然后从偏移处开始提取2位字符,结果是10的值)

%date:~8,2% 表示指针从左向右偏移8位,然后从偏移处开始提取2位字符,结果是21日的值)

%date:~5%    表示指针从左向右偏移5位,然后提取所有的值

%date:~-5%  表示指针反方向偏移,从最右端开始,偏移5位,然后从指针处提取左边的所有数值。

%Time:~0,2% 表示从左向右指针向右偏0位,然后从指针偏移到的位置开始提取2字符,结果是14(小时)

%Time:~3,2%  表示指针从左向右偏移3,然后从偏移处开始提取2位字符,结果是30(分钟)

%Time:~6,2%  表示指针从左向右偏移6,然后从偏移处开始提取2位字符,结果是37(秒钟)

@echo off
echo %Date:~0,4%年%date:~5,2%月%date:~8,2%日%Time:~0,2%:%time:~3,2%:%time:~6,2%
@ping -n 60 127.1>nul
echo %Date:~0,4%年%date:~5,2%月%date:~8,2%日%Time:~0,2%:%time:~3,2%:%time:~6,2%
pause

find 在一个文件或多个文件中搜索指定的文本字符串。当搜索指定的文件后,find 将显示出包含指定字符串的所有行。
find [/v] [/c] [/n] [/i] "string" [[Drive:][Path]FileName[...]]

  • /v    显示所有不包含指定 string 的行。

  • /c    计算包含指定 string 的行并显示总数。

  • /n    将文件行号置于每行开头。

  • /i    指定搜索不区分大小写。

  • "string"    必需。指定要搜索的字符组。必须将 string 包含在引号之内(即,"string")。在用 find 命令指定的文件名或扩展名中不能使用通配符(* 和 ?)

  • [Drive:][Path] FileName    指定要在其中搜索指定字符串的文件的位置和名称。

  • /?    在命令提示符显示帮助。


自定义变量

自定义变量就是由我们来给他赋予值的变量,要使用自定义变量就得使用set命令

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

保存为BAT执行,我们会看到CMD里返回一个    "我是值"

如果我们想让用户手工输入变量的值,而不是在代码里指定,可以用用set命令的/p参数

@echo off
set /p var=请输入变量的值
echo %var%
pause

var变量名    =号右边的是提示语,不是变量的值变量的值由我们运行后自己用键盘输入!

eg、批量添加路由,由于下一跳地址是经常变动的,所以需要手动输入变量

@echo off
set /p gw=请输入×××网关:
route add 10.10.0.0 mask 255.255.0.0 %gw%
route add 10.17.0.0 mask 255.255.0.0 %gw%
route add 10.15.0.0 mask 255.255.0.0 %gw%
route add 192.168.0.0 mask 255.255.0.0 %gw%
route print
pause