原创
最近更新: 2023/04/29 19:13

Windows cmd命令详解

概述

批处理脚本语言是微软Windows系统自带的原生开发语言,不需要任何环境构建就能执行的脚本。

应该注意的是,如果脚本中涉及中文(非ASCII字符)时,应将编码调整为ANSI,否则会乱码。

Hello world

@echo off
echo "hello world"
:: 暂停,屏幕上显示“请按任意键继续. . .”,一般用于脚本结束时给用户看执行结果
pause
:: 也可以 pause > nul,nul表示空文件,暂停时不会显示提示语

路径的表示方法

batch批处理脚本最重要的一个用途是处理文件和目录,往往出现在分支判断语句if-else中或循环语句for中。

Windows的路径不区分大小写,分隔符既可以是斜杠/也可以是反斜杠\

样例 说明
d:/1/2/3.txt 绝对路径
./a.txt 相对路径,.表示工作目录
d:/1/2/*.txt 通配符*匹配文件名中的任意字符串
* 单独的通配符表示工作路径下的所有文件
../ 父目录

内部命令

内部命令是系统内置的命令,可以通过help命令查看所有的内部命令。也可以通过command /?的方式查看特定命令的用法。

常用的内部命令介绍如下:

文件和目录操作

命令 功能 更多介绍
cd, chdir 显示当前目录名或改变当前目录 变量%cd%为当前工作路径
dir 列出目录中的文件和子目录
md, mkdir 创建目录 可以创建多层目录
move 移动或重命名文件或目录
ren, rename 重命名文件
del, erase 删除文件或目录
rd, rmdir 删除目录 /s可以删除目录树
copy 复制 可以有多个源文件,但目标文件只能有一个
xcopy 复制文件和目录树 功能选项比较多
robocopy 高级复制工具 适用于需要高可靠性以及大量文件的场景
attrib 显示或更改文件属性 可以给文件设置只读、隐藏等属性

系统相关指令

命令 功能 更多介绍
date 显示或设置日期 变量%date%为当前日期和星期
time 显示或设置时间 变量%time%为当前时间,精确到百分秒
start 启动一个单独窗口以运行特定程序或命令 可以是一个程序、文件、网页等,系统会自动打开合适的程序
systeminfo 显示系统信息
tasklist 显示所有进程和服务 可以设置显示的格式,并筛选需要的内容
ver 显示windows版本
diskpart 配置磁盘分区 比带UI的磁盘管理功能强,需要管理员权限
recover 从损坏的磁盘中恢复可读取的信息
shutdown 关机 可以设置重启或者定时等

命令行窗口相关指令

命令 功能 更多介绍
cmd 打开另一个命令行窗口 可以设置新窗口的属性和行为
call 调用批处理文件 call [drive:][path]filename [batch-parameters]
echo 回显消息 echo on/off可启用或关闭命令回显,echo=表示打印一个空行
exit 退出 可以设置返回值errorlevel
color 设置默认控制台前景和背景颜色 只生效一次
title 设置cmd窗口标题
prompt 更改 Windows 命令提示 即输入每一行命令时,前面C:\WINDOWS\system32>的部分
cls 清除屏幕 乱糟糟的屏幕确实很烦人
more 逐屏显示输出

其他常用工具

命令 功能 更多介绍
type 显示文本文件内容
find 搜索字符串 显示输入中含有特定字符串的行,常与管道符`
findstr 搜索字符串 find的升级版,功能更强大,能匹配简单的正则表达式
sort 对输入进行排序 按行排序
tree 用图形方式显示文件夹树
comp 比较两个文件区别 按照字节比较,适用于二进制文件
fc 比较两个文本文件区别 适用于文本文件

外部命令

外部命令会执行电脑中的某个程序,程序可能是系统预装的,也可能是用户安装的,如

  • ping
  • ftp
  • java
  • ...

常用的windows预装的外部命令基本是网络相关的程序,介绍如下:

命令 功能 更多介绍
net (网络)管理指令 有很多功能,比如用户管理、服务管理、查询网络信息、共享资源管理等
ipconfig 显示网络适配器信息
ping 测试网络连通性 有很多可选项
telnet 连接远程端口 明文通信,注意安全
ssh 远程加密连接
ftp 远程文件传输
tracert 路由追踪 显示本机到特定地址过程中经过的路由器IP地址
route 显示路由表
arp 显示IP地址与MAC地址的映射关系
nslookup 查询域名的DNS信息
reg 注册表编辑器相关指令

基本语法

变量操作set

set可以用于变量的赋值,显示等操作。此处变量又称作环境变量。环境变量的值全都是字符串。

Windows的环境变量名不区分大小写。

变量的取值需要在其前后加上百分号%

注意:set后面的赋值语句中不应带有任何多余的空格,Windows会将空格解释为变量或字符串的一部分。

:: 不带空格的情况
set aa=1
:: 下面一行输出"1"
echo %aa%
:: 带空格的情况
:: 变量名为"a ",值为字符串" 2"
set aa = 2
echo %aa %

:: 显示所有a开头的变量
set a
:: 删除变量,等号后面什么都不加
set aa=
:: 下面一行输出“环境变量 aa 没有定义”
set aa

交互式操作

set /p表示从标准输入流读入一个字符串。

:: 将用户输入的字符串存入变量中
set /p a=

字符串操作

字符串比较

批处理命令中,字符串的比较是逐字比较编码的。windows的比较运算符比较特殊:

  • 相等:==equ
  • 不等于:neq
  • 大于:gtr
  • 大于等于:geq
  • 小于:lss
  • 小于等于:leq

应当注意的是,==的两边可以没有空格,但其他比较运算符需要空格分隔。

@echo off
set a=1234
set b=12245
if a gtr b echo a大于b
pause

可以用中括号把字符串括起来,该语法可以用来表示空字符串。

@echo off
set a=
if [%a%]==[] echo a是空字符串
pause

字符串拼接

@echo off
set a=hello
set b=world
:: c=hello world
set c=%a% %b%
echo %c%
pause

字符串截取

使用%变量名:~起始位置,截取长度%来截取字符串,逗号和截取长度可省略,表示截取到末尾。起始位置可以用负数,表示倒数第几个。

@echo off
set a=1234567890
:: 截取前五个字符12345
set b=%a:~0,5%
:: 截取最后五个字符67890
set b=%a:~-5%
echo %b%
pause

字符串替换

使用%变量名:原子串=替换子串%来进行字符串的部分替换。

@echo off
set a=hello Alice!
set b=%a:Alice=Bob%
:: b=hello Bob!
echo %b%
pause

运算符

算术运算符

使用set /a执行算术运算。

基本的算术运算符都有:+加、-减、*乘、/除、%取余、()括号。

set /a (1+2)*9%5
:: 可以将算数运算的结果赋值给一个变量
set /a a=(1+2)*9%5

重定向运算符

>, >>, <可以输入输出数据流重定向,箭头方向表示数据的流向。

>表示覆盖输出,>>表示追加输出,<表示输入。

:: 将字符串输出到文本文件,会覆盖原本的文件内容
echo hello world > a.txt
:: 将字符串追加输出到文本文件,内容会接在原本文件的末尾
echo hello world >> a.txt
:: 将文本内容作为指令的输入
sort < a.txt

命令连接运算符

&, &&, ||,连接多条命令,根据前一条命令执行结果有不同的执行过程。

:: & 表示单纯的连接,连接起来的命令顺序执行,命令执行成功与否不影响后续命令的执行
:: && 表示:仅当前一条执行成功时,执行后面的命令
:: 下面一行不会输出"ok"
aaaa && echo "ok"
:: || 表示:仅当前一条执行失败时,执行后面的命令
:: 下面一行不会输出"ok"
echo "haha" || echo "ok"

管道运算符

|将前一条命令的输出作为后一条命令的输入。常用于在大段输出之中进行过滤筛选操作。

:: 在进程列表中找到explorer的相关信息
tasklist | find /i "explorer.exe"

if-else分支控制语句

if-else语句用于控制流的分支判断,如果语句返回true,则运行if后面的语句,返回false则运行else后面的语句。

用法一:判断变量的值

该用法是if语句最基本的用法,配合字符串比较语句使用。

:: /I 表示不区分大小写
:: IF [NOT] [/I] string1==string2 command
@echo off
set a=123

:: 单行的if
if %a%==123 echo 只有if的情况可以不加括号

:: 单行的if-else
if %a%==123 (echo 需要用括号括起来) else echo 这里的括号可加可不加

:: 多行的if-else
if %a%==123 (
echo 可以跨行
echo 可以有多行语句
)else (
echo else关键字不能作为一行的开头
echo else与后面的括号之间需要有空格分开
)
pause > nul

用法二:判断文件是否存在

非常常用。

:: IF [NOT] EXIST filename command
if exist d:\a.txt (echo 存在) else (echo 不存在)

用法三:判断上条命令的执行情况

windows会将命令执行的结果保存在变量%ERRORLEVEL%中。

:: IF [NOT] ERRORLEVEL number command
:: 当上一条命令返回的错误码值大于或等于某个值的时候,将执行command操作
:: 一般情况下,成功执行返回0,非零值都是失败的情况
:: 等价于 IF %ERRORLEVEL% GEQ number command
@echo off
:: 下面一行copu不是一个命令,所以会执行失败,返回一个非0的错误码
copu a.txt bak/b.txt
echo errorlevel=%errorlevel%
if errorlevel 1 echo SUCCESS
pause

::%ERRORLEVEL%的一个用例
goto answer%ERRORLEVEL%
:answer0
echo Program had return code 0
:answer1
echo Program had return code 1

用法四:判断环境变量是否存在

:: IF DEFINED variable command
if defined a (echo a被定义了) else a未被定义

for循环控制语句

for语句用于执行循环控制流,脚本会遍历给定的集合,并执行循环体。循环体部分也可用括号实现多行语句。

batch脚本的循环语句功能较弱,如果要实现复杂的循环判断逻辑,建议使用goto语句。

用法一:手动指定要遍历的集合

FOR %variable IN (set) DO command [command-parameters]

最基本的用法,集合是字符串的集合,用英文逗号或者空格分隔。

此处的变量名只能用单一字母,且区分大小写,所以所以 %a 不同于 %A。

:: 如果是在批处理文件中使用for语句,那么应该双写百分号
FOR %%v IN (alice,bob,charlie) DO echo %%v

用法二:遍历目录下的文件或子目录

FOR [/d] %variable IN (path/*) DO command [command-parameters]

集合部分是一个带通配符的路径,此时系统会将路径匹配到对应目录下的文件。

添加/d选项后,匹配对应目录下的子目录。

:: 匹配文件
FOR %%v IN (./path/*) DO echo %%v
:: 匹配子目录
FOR /d %%v IN (./path/*) DO echo %%v

应该注意的是,此处的循环变量会存储文件的绝对路径,如果要存储部分路径(如文件名、扩展名等),需要进行变量名扩展操作。扩展操作在for /?中有详细介绍,此处仅介绍几个常用的扩展:

  • %~i :删除引号
  • %~di:取盘符
  • %~pi:取盘符内的目录路径
  • %~ni:取文件名部分
  • %~xi:取扩展名部分
  • %~ai:取文件属性
  • %~ai:取文件日期/时间
  • %~zi:取文件大小

将上述扩展组合使用可以得到复杂结果:

  • %~dpi:仅取路径%i的父目录部分
  • %~nxi:仅取路径%i的文件名和扩展名部分
:: 打印工作目录下所有文件名
FOR %%i IN (*) DO echo %%~nxi

:: 使用ffmpeg工具将目录下所有.ogg文件转换成.mp3文件
for %%v in (./*.ogg) do ffmpeg -i "%%~dpnxv" -ar 44100 -ab 320k -f mp3 -acodec libmp3lame -y "%%~dpnv.mp3"

用法三:遍历目录树

FOR /R [[drive:]path] %variable IN (set) DO command [command-parameters]

检查以 [drive:]path 为根的目录树,指向每个目录中的 FOR 语句。如果在 /R 后没有指定目录规范,则使用当前目录。

系统会将目录树中每一个目录拼接上set中的每一项,构成一个新的路径(目录或文件),然后赋值给循环变量。如果set仅为一个单点.字符,则枚举该目录树。

:: 给每个目录都匹配一个1.txt和2.exe
FOR /r ./path/ %%v IN (1.txt,2.exe) DO echo %%v

用法四:遍历数列

FOR /L %variable IN (start,step,end) DO command [command-parameters]

for循环最普通的用法。

:: 列举1~20的奇数
FOR /L %%v IN (1,2,20) DO echo %%v

用法五:按行读取文本文件

FOR /F ["options"] %variable IN (file-set) DO command [command-parameters]

读取文件并按行赋值给循环变量,可以将每行进行拆分并设置多个变量进行承接

用法很复杂,详见for /?,此处仅做简单介绍。

:: 读取文件并按行输出
FOR /f %%v IN (samlpe.txt) DO echo %%v

其他语句

注释符号

::rem用于行注释,注释的内容不会被执行。

:: 这里是注释
rem 这里也是注释

隐藏符号

@用在一条命令的开头,使该命令不在屏幕上回显。

:: 大多数情况下就这一个用法
@echo off

跳转

:用于标识和命名代码中的一个位置,goto可以直接跳转到这个位置。一般需要和判断语句结合使用。

由于batch命令在变量和控制流处理方面非常的瘸脚,所以善用goto语句可以有效简化脚本。

:: 会跳过第二行的命令
goto sect2
echo "1"
: sect2
echo "2"

实用脚本

文件名搜索

Windows 自带的文件搜索功能非常的垃圾,很多情况下可能根本搜不出东西来,因此不如直接写一个脚本来进行文件搜索。

@echo off

set searchtempfile=searchtempfile

: start
echo 请输入查询关键字:
set /p keyword=

echo=
echo 搜索进行中,请稍等……
echo=

for /r %%d in (.) do (
    for %%f in ("%%d"/*) do echo %%~f >> %temp%\%searchtempfile%
)

findstr %keyword% %temp%\%searchtempfile%
del %temp%\%searchtempfile%

echo=
echo 查找完毕,请按任意键开始一次新的查找
pause > nul
cls
goto start

评论区