windows-bat批处理脚本编程总结
常用命令
cd [/d] [drive:][path]
切换工作目录,/d
跨磁盘dir [drive:][path][filename] [options]
列举文件夹信息/b
只显示具体文件夹和文件信息,不显示统计信息和.
,..
;/s
递归/a
按属性显示,/ad
只显示文件夹,/a-d/
显示非文件夹/o
按某种方式排序,/on
,按名字,/os
按大小;
md [drive:][path]
创建文件夹rd [/s][/q] [drive:]path
删除文件夹,/s
递归,/q
无需确认xcopy source [destination] [options]
拷贝文件或文件夹/s
递归复制目录与子目录,排除空文件夹;/e
递归复制目录与子目录,包括空文件夹,/s /e
同/e
/t
创建目录结构,但不复制文件;不包含空目录;/t /e
创建目录结构,包括空文件夹/y
关闭覆盖确认,一次设置即可
copy [options] source [/a|/b] destination [/a|/b]
拷贝一个或多个文件move
移动一个或多个文件,重命名文件夹-
to move one or more files:
move [/y | /-y] [drive:][path]filename1[,...] destination
-
to rename a directory:
move [/y | /-y] [drive:][path]dirname1 dirname2
-
ren [drive:][path]filename1 filename2.
重命名文件,不能跨文件夹;改前缀或后缀ren *.txt *.csv
del [/p] [/f] [/s] [/q] [/a[[:]attributes]] names
删除若干文件,会保留文件夹;/s
递归,/f
强制type [drive:][path]filename
显示一个或多个文件的内容
帮助
在cmd中输入命令 /?
,如for /?
即可查看系统给出的帮助文件。
注释
REM为注释命令,该命令后的内容不被执行,但能回显。
回显
@
符号放在命令前将关闭该命令的回显,无论此时是否echo on。echo
可以打开、关闭回显,输出提示信息。
echo的功能
- 打开、关闭回显
echo on
/echo off
- 输出提示信息
echo message
输出空行
echo.
,.
要紧跟在echo
后面,还可以用:;"/+[]
等任一代替。
- 应答命令,相当于命令对话时输入消息并回车。
echo response | 命令
暂停
pause
暂停执行并给出提示
程序返回码
每个命令结束可以查看是否执行成功,默认值为0,非0表示出错。
echo %errorlevel%
设置cmd窗口标题
title 新标题
设置控制台前景和背景色
color [attr]
attr
是代表控制台的背景色和前景色的两个十六进制值
0
黑色1
蓝色2
绿色3
湖蓝色4
红色5
紫色6
黄色7
白色8
灰色9
淡蓝色A
淡绿色B
淡浅绿色C
淡红色D
淡紫色E
淡黄色F
亮白色
如:
color 07
在文本中搜索字符串
find [/v] [/c] [/n] [/i] [/off[line]] "string" [[drive:][path]filename[ ...]]
/v
显示所有未包含指定字符串的行。/c
仅显示包含字符串的行数。/n
显示行号。/i
搜索字符串时忽略大小写。/off[line]
不要跳过具有脱机属性集的文件。"string"
指定要搜索的文字串,[drive:][path]filename
指定要搜索的文件
如:
find /n /i "find" test.md
将输出文件中包含find
的行及行号。
系统变量
-
%DATE%
系统变量 返回当前日期。使用与 date /t 命令相同的格式。 -
%TIME%
系统变量 返回当前时间。使用与 time /t 命令相同的格式。 -
%ERRORLEVEL%
系统变量 返回上一条命令的错误代码。通常用非零值表示错误。 -
%HOMEPATH%
系统变量 返回用户主目录的完整路径。基于主目录值而设置。用户主目录是在“本地用户和组”中指定的。 -
%NUMBER_OF_PROCESSORS%
系统变量 指定安装在计算机上的处理器的数目。 -
%OS%
系统变量 返回操作系统名称。 -
%PATH%
系统变量 指定可执行文件的搜索路径。 -
%RANDOM%
系统变量 返回 0 到 32767 之间的任意十进制数字。由 Cmd.exe 生成。 -
%CD%
本地变量 返回当前目录字符串。 -
%APPDATA%
本地变量 返回默认情况下应用程序存储数据的位置。 -
%TEMP%
和%TMP%
系统和用户 返回对当前登录用户可用的应用程序所使用的默认临时目录。有些应用程序需要 TEMP,而其他应用程序则需要 TMP。 -
%ALLUSERSPROFILE%
本地变量 返回“所有用户”配置文件的位置。 -
%CMDCMDLINE%
本地变量 返回用来启动当前的 Cmd.exe 的准确命令行。 -
%CMDEXTVERSION%
系统变量 返回当前的“命令处理程序扩展”的版本号。 -
%COMPUTERNAME%
系统变量 返回计算机的名称。 -
%COMSPEC%
系统变量 返回命令行解释器可执行程序的准确路径。 -
%HOMEDRIVE%
系统变量 返回连接到用户主目录的本地工作站驱动器号。基于主目录值而设置。用户主目录是在“本地用户和组”中指定的。 -
%HOMESHARE%
系统变量 返回用户的共享主目录的网络路径。基于主目录值而设置。用户主目录是在“本地用户和组”中指定的。 -
%LOGONSERVER%
本地变量 返回验证当前登录会话的域控制器的名称。 -
%PATHEXT%
系统变量 返回操作系统认为可执行的文件扩展名的列表。 -
%PROCESSOR_ARCHITECTURE%
系统变量 返回处理器的芯片体系结构。 -
%PROCESSOR_IDENTFIER%
系统变量 返回处理器说明。 -
%PROCESSOR_LEVEL%
系统变量 返回计算机上安装的处理器的型号。 -
%PROCESSOR_REVISION%
系统变量 返回处理器的版本号。 -
%PROMPT%
本地变量 返回当前解释程序的命令提示符设置。由 Cmd.exe 生成。 -
%SYSTEMDRIVE%
系统变量 返回包含 Windows server operating system 根目录(即系统根目录)的驱动器。 -
%SYSTEMROOT%
系统变量 返回 Windows server operating system 根目录的位置。如C:\WINDOWS
-
%USERDOMAIN%
本地变量 返回包含用户帐户的域的名称。 -
%USERNAME%
本地变量 返回当前登录的用户的名称。 -
%USERPROFILE%
本地变量 返回当前用户的配置文件的位置。 -
%WINDIR%
系统变量 返回操作系统目录的位置。如C:\WINDOWS
自定义变量
要使用自定义变量就得使用set命令
@echo off
set var="hello var"
echo %var%
pause
set /p var=please input your value
echo %var%
pause
标号
以:
开头的字符行被视作标号。
- 有效标号,冒号后紧跟一个以字母数字开头的符号,goto语句可以识别
- 无效标号,冒号后紧跟一个非字母数字的特殊符号,goto无法识别,可以起到注释作用。
所以
::
也常用作注释符号,且不论是否echo on都不会回显,因为解释器认为这是一条无效的命令行。
goto
goto
可以跳转到以:
开头的标号处,执行标号后面的命令
:start
set /a var+=1
echo %var%
if %var% leq 3 goto :start
pause
goto :start
的:
可以省略
调用另一个批处理
- 调用另一个批处理命令
call command
和直接执行命令效果一样
set telnumber=017246352391
set cmdstr=echo %telnumber%
call %cmdstr%
pause
- 调用本文件内命令段(相当于函数)
call :label arguments
被调用的命令段以标签:label名
开头,以命令goto :eof
结尾。
call :telephone 10086
exit /b
:telephone
@echo start to call telephone %1
@pause
@goto :eof
另一个示例
rem %~0 is current file
call :sub %~0
pause
exit /b
:sub
@echo off
rem %~1 is parameter 1
echo remove quote: %~1
echo file path: %~f1
echo drive: %~d1
echo path: %~p1
echo name: %~n1
echo ext: %~x1
echo short: %~s1
echo attribute: %~a1
echo date time: %~t1
echo size: %~z1
echo drive and path: %~dp1
echo name and ext: %~nx1
echo attribute date time size file path: %~ftza1
echo.
goto :eof
- 调用另一个批处理程序
call [drive:][path]filename [batch-parameters]
调用的其它批处理程序。filename 参数必须具有.bat
或.cmd
扩展名
文件属性
attrib [{+-}{RASH}] [[drive:][path]filename] [/S [/D]]
+
设置属性-
清除属性R
只读A
存档,备份程序会认为该文档已经备份过S
系统,表示文件是操作系统的一部分H
隐藏,默认情况下用户不可见/S
处理当前文件夹及其子文件夹中匹配的文件/D
处理文件夹
echo. > tmp.txt
attrib +r tmp.txt
pause
attrib +a +h tmp.txt
pause
attrib -r -h tmp.txt
pause
del tmp.txt
变量延迟
在没有开启变量延迟的情况下,某条命令行中的变量改变,必须到下一条命令才能体现。
请看以下示例
set var=1
set var=2 & echo %var%
pause
输出结果是1
如果开启了变量延迟(赋值),在读取了一条完整的语句之后不立即对该行的变量赋值,而是在某个单条语句执行之前再进行赋值。
setlocal enabledelayedexpansion
set var=1
set var=2 & echo !var!
pause
输出结果是2
开启变量延迟需要启动语句setlocal enabledelayedexpansion
且变量要使用一对!!
包括起来。
再看下一个例子
@echo off
for /l %%i in (1,1,5) do (
set var=%%i
echo %var%
)
得不到正确答案,因为for后面的一对圆括号()
内的语句也当作一行
启动变量延迟后可以得到正确结果
setlocal enabledelayedexpansion
@echo off
for /l %%i in (1,1,5) do (
set var=%%i
echo !var!
)
特殊符号
@
当前命令行回显屏蔽,
echo off可以关闭后面的批处理命令回显,但当前行不能关闭,需要使用
@
;
%
批处理变量引用,引用变量使用%var%
,调用程序外部参数使用%1
-%9
;
for循环的变量在cmd窗口中使用
%var
,在脚本中用%%var
;
<
,>
,>>
重定向|
管道^
转义<
,>
,&
&
,&&
,||
组合命令()
括号中可以包括多行命令,这些命令将被看成一个整体,视为一条命令。
分支
if condition command
满足某条件即执行command
condition有以下几种
[not] errorlevel number
需要放在某个命令后面,通过errorlevel来判断执行命令的返回值
dir c:
if errorlevel 0 echo ok
[not] str1==str2
@echo off
set str1="hello"
set str2="hello"
if %str1%==%str2% echo str1 eq str2
[not] exist filename
判断文件或目录是否存在
@echo off
if exist test.bat echo exist
if not exist test.bat echo not exist
if condition (...) else (...)
if condition (
command1
) else (
command2
)
如:
@echo off
if exist test.bat (
echo exist
) else (
echo not exist
)
循环
格式
for [/d/l/r/f] %%var in (set) do command [command-parameters]
/d /l /r /f
for循环选项%%var
获取到的循环变量(set)
循环范围或集合command
对每个循环变量执行的命令command-parameters
命令参数
command [command-parameters]
可以使用一个小括号括起来
FOR循环选项
FOR /D
仅匹配目录
for /d %%var in (set) do command [command-parameters]
如果集中包含通配符(*
,?
),则指定与目录名匹配,而不与文件名匹配。
如果set也包含通配符,将对于set相匹配的每个目录(不是目录中的文件组)执行指定的command。
@echo off
for /d %%i in (C:\*) do echo %%i
pause
会把C盘根目录下的全部目录名字打印出来,而文件名字一个也不显示
FOR /R
递归
for /r [[drive:]path] %%var in (set) do command [command-parameters]
检查以 [drive:]path
为根的目录树。
如果在 /R
后没有指定目录,则使用当前目录。
如果set仅为一个单点(.)字符,则枚举该目录树。
请注意2点:
- set中的文件名如果含有通配符(``或
*
),则列举/R
参数指定的目录及其下面的所用子目录中与set相符合的所有文件,无相符文件的目录则不列举。 - 如果set中为具体文件名,不含通配符,则枚举该目录树(即列举该目录及其下面的所有子目录),而不管set中的指定文件是否存在。这与前面所说的单点(.)枚举目录树是一个道理,单点代表当前目录,也可视为一个文件。
@echo off
for /r C:\ %%i in (*.exe) do echo %%i
pause
把C盘根目录,和每个目录的子目录下面所有的EXE文件都列出来
@echo off
for /r %%i in (*.bat) do echo %%i
pause
递归搜索当前目录下的bat文件并显示出来。
@echo off
for /r C:\ %%i in (everything.exe) do echo %%i
pause
枚举C盘所有目录,只为枚举出boot.ini所在的目录(多为无效目录)
@echo off
for /r C:\ %%i in (everything.exe) do if exist %%i echo %%i
pause
枚举C盘所有目录,如果目录中的boot.ini存在,则显示出来。
FOR /L
序列
for /l %%var in (start, step, end) do command [command-parameters]
该set表示以增量形式从开始到结束的一个数字序列。左右都是闭区间,step可以为负。
@echo off
for /l %%i in (1,1,5) do (
echo %%i
)
会打印
1 2 3 4 5
@echo off
for /l %%i in (5,1,5) do (
echo %%i
)
会打印
5
@echo off
for /l %%i in (5,-1,1) do (
echo %%i
)
会打印
5 4 3 2 1
FOR /F
迭代
for /f ["options"] %%var in (file-set) do command [command-parameters]
for /f ["options"] %%var in ("string") do command [command-parameters]
for /f ["options"] %%var in ('command') do command [command-parameters]
file-set
代表一个或多个文件"string"
代表字符串'command'
代表命令
带引号的字符串"options"包括一个或多个指定不同解析选项的关键字。
这些关键字为:
eol=c
指定一个行注释符的结尾,默认以使用;
为行首的一行为注释行;skip=n
在文件开始时忽略的行数,默认为1,最小为1;delims=xxx
分隔符集,默认为空格和跳格键;tokens=m-n
提取列,提取每一行的第m小节的内容。默认为1,最大31。可以用该命令来指定提取文本信息。tokens=m
提取第m列。tokens=m,n
提取第m列和第n列。tokens=m-n
提取第m列至第n列。tokens=*
删除每行前面的空格。忽略行首的所有空格。tokens=m*
提取第m列以后的所有字符,星号表示剩余的字符。tokens=m,*
提取第m列以后的所有字符,星号表示剩余的字符。
usebackq
使用后引号;- 未使用usebackq时:
- file-set表示文件,但不能含有空格
- 双引号表示字符串,即"string"
- 单引号表示执行命令,即’command’
- 使用参数usebackq时:
- file-set和"file-set"都表示文件,当文件路径或名称中有空格时,就可以用双引号括起来
- 单引号表示字符串,即’string’
- 后引号表示命令执行,即
command
- 未使用usebackq时:
in (file-set)
for会将文件依次打开遍历其中的行
假如有文件tmp.txt
内容如下
;comment
11 12 13-14,15
21 22 23-24,25
31 32 33-34,35
41 42 43-44,45
51 52 53-54,55
示例1
@echo off
for /f "eol=; tokens=1,3* delims=,- " %%i in (tmp.txt) do (
echo %%i %%j %%k
)
pause
输出结果为
11 13 14,15
21 23 24,25
31 33 34,35
41 43 44,45
51 53 54,55
eol=;
表示;
开头的行尾注释行
tokens=1,3*
将第1段、第3段和剩余字段分别赋值给变量i
、j
、k
;
delims=,-
减号后有一空格,以逗号减号和空格为分隔符(空格必须放在最后)
@echo off
for /f "eol= delims=" %%i in (tmp.txt) do (
echo %%i
)
pause
输出结果为(包含注释行)
;comment
11 12 13-14,15
21 22 23-24,25
31 32 33-34,35
41 42 43-44,45
51 52 53-54,55
in ("string")
@echo off
for /f "tokens=1,3" %%i in ("hello good morning") do (
echo %%i %%j
)
pause
运行结果为
hello morning
in ('command')
@echo off
for /f "eol=; tokens=1,3* delims=,- " %%i in ('type tmp.txt') do (
echo %%i %%j %%k
)
pause
输出结果为
11 13 14,15
21 23 24,25
31 33 34,35
41 43 44,45
51 53 54,55