[提炼再版]dos命令和批脚本
当前文章版本号V1.5.5
简介
现在大家一般都是使用的window系统,但是有的时候就是会有一些萌新弄不清各种涵盖安装,出bug等等各种各样的问题
是的,我们程序员急需一款能够快速编写的脚本软件,最好满足下面几个要求!
- 非常强的可传播性,这样我们才能传脚本给那些毛都不知道,只想浪费我们时间的人用
- 非常高的便携性,不需要安装任何环境,不需要配置乱七八糟的东西,拿到一台电脑马上就可以开始编写
- 非常高的兼容性,不论是记事本,还是专业的IDE都可以编写并且运行
现在知道了我们为什么要学,让我们来开始看看window自带的dos脚本吧
为什么会有这篇文章
在这之前我曾经也做过一片dos批命令的命令大全,源自于bilbil上面某一个up主的讲课内容,但是因为课程过于混乱,条理非常不严谨,导致我的那一篇文章最终沦为字典
为了能够真正的做一个快速入门以及掌握核心知识,方便今后自己复习或者他人查阅的时候能够看到重点,于是这一篇文章诞生了
本文章将会从下面几个方面开始全方面了解我们的dos批命令,让我们得以更快的操作计算机
我一直坚信,如果一个技术能广泛传播,那么这个技术一定是带给了使用人方便便利,或者是可以完成某些具体的功能,.必须从功能出发,我们才能更快的了解到技术存在的实际意义,所以我尽量从完成功能的角度带大家看看dos脚本,并且在之后我会附上几个实例
正式开始
正式编写代码之前,我们需要处理一些问题
处理编码错误问题
dos命令行的中文系统默认的编码格式是gbk,我们需要手动修改成utf-8,或者使用powershell
如何手动更改呢?或者说如何一次更改就可以一劳永逸呢?😎
- Win+R,输入regedit打开注册表编辑器
- 依次找到 HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor\
- 右键新建一个字符串值(S),取名叫Autorun,值设为@chcp 65001>nul
- 确定保存退出
以上,就完成了编码的自动修改,和默认为UTF8是一样的效果。
关于编译器的选择
dos脚本默认在每个window上面都能运行,你可以新建一个记事本,然后把后缀.txt
改为.bat
就成为了一个可执行,可移植的dos脚本
同时你也可以使用更加强大的编译器,他们会给你更加舒适的编写体验
notepad++
vscode
美化我们的命令行
给我们的命令行加上颜色
如果你执意想要在命令行上运行,而且希望能够让我们的命令行更加美观,这个时候我们需要使用到命令行的颜色代码
设置默认的控制台前景和背景颜色。
颜色属性由两个十六进制数字指定 -- 第一个
对应于背景,第二个对应于前景。每个数字
可以为以下任何值:
0 = 黑色 8 = 灰色
1 = 蓝色 9 = 淡蓝色
2 = 绿色 A = 淡绿色
3 = 浅绿色 B = 淡浅绿色
4 = 红色 C = 淡红色
5 = 紫色 D = 淡紫色
6 = 黄色 E = 淡黄色
7 = 白色 F = 亮白色
由帮助我们可以得知需要让命令行变色需要两个值
一个是背景的颜色,一个是文字的颜色
比如根据上表可得,我们输入
color 6A
就可以得到一个背景是黄色(备注:第一个数字是6,对应上表的黄色),然后文字是淡绿色的命令行
不过最好还是不要看了,我刚刚看了一下,这个配色太死亡了
给我们的命令行指定标题title
使用命令title "字符串"
就可以让我们的cmd变成自己想要的名字
示范
title "转啊转~"
显示结果
可以看到我们cmd的标题已经成功变成转啊转了
基本语法
注释
dos命令中的注释使用
rem
开头
dos命令中没有多行注释,如果想要使用多行注释请在每一行前面都写上rem
rem 这里是都是不会被执行的内容
注释里面的内容不会影响代码执行,只是为了方便我们编写代码的时候能够更方便的找到每一行代码是干什么用的
打印输出语句echo
我们需要让程序的运行结果和过程让我们看得到,所以一个输出语句是非常有必要的
几点注意
- dos脚本不需要使用
分号(;)
,同时打印一个字符串的时候不需要用引号引起来(除非是一个有空格的字符串)
// 关闭前面盘符的一大串前缀,只输出结果
@echo off
// 输出hello world
echo hello world
// 注意,此处如果不暂停,程序会一闪而过
pause
可以运行的程序如下:
@echo off
echo hello world
pause
变量和标识符
- 命名一个变量之前必须使用
set
- 命名一个变量如果是整形需要使用
/a
作为参数
// 命名一个变量a
set a="haha"
// 命名一个整形变量a
set /a a=5
!!! note 警告!
这个命名的等号两边不得有任何空格
a="haha" ✔️
a = "haha" ❌
ccs(conclusion):
拥有一个变量几乎是所有编程语言最基础的东西,整个编程的大厦都压在这小小的变量上面,在dos语言中
变量的命名还算简单,只是调用的过程相对复杂,有了这个变量,我们之后程序的开展就有了基础
如何从用户那里接受一个参数呢?
同样需要使用set命令
,但是此时我们要加的参数为/p
@echo off
set /p a=请输入一个变量
echo %a%
pause
此时我们就成功接受一个变量并且赋值给了a
ccs
只是执行一个单一命令或者单一进程的脚本是短命,无法传播,无法修改,
可以说生命力已经被限制了,这个时候我们需要让用户自主输入变量,而且不是程序自己生成
这样就可以根据需求定制用户想要的功能
调用其他的批处理文件
使用
call
命令可以调用其他的批处理文件,而且可以导入参数
在被调用的文件里,可以使用%1
%2
%3
来接受参数
文件1
@echo off
call 文件2 测试输出
pause
文件2
@echo off
echo %1
pause
可以看到,我们在文件1
里面没有输出语句,只有在文件2里面才有输出语句,所以很明显是文件1
调用了我们的文件2
并且传递了一个参数
css
单个批处理文件过于繁杂冗长会导致编写的时候错误增加
于是我们提出了模块化编程的思想,让每一个代码块各司其职,让文件分割
但是仅仅只是分割的话就本末倒置,我们需要让他们依旧可以相互联系,成为整体
所以,使用call命令,传递参数,调用其他批命令吧!
运算符
a%b 取余操作
+,-,*,/ 都是没有问题的
& 表示两条命令或语句同时执行的意思
&&和|| 这是一对含义截然相反的命令符
&&表示如果它之前的语句成功执行,将执行它之后的语句
||则表示如果它之前的语句执行失败,将执行它之后的语句;在某些场合,它们能替代 if……else…… 语句
特殊的符号乘号(*)与问号(?)
在dos脚本语言里面,这两个都是通配符的意思,为的就是我们能更加简单的操作文件
比如此处有3个文件
file1.txt
file2.txt
file3.txt
这个时候如果我们想要选择上面所有的文件需要一个又一个的输入文件名字,那么有没有办法让我们可以一口气选中所有的文件呢?
答案是有的,使用乘号(*)
通配符,匹配他们所有的后缀.txt
我们输出命令如下
*.txt
这样就可以匹配到我们上面所有的文件了
我们的乘号通配符匹配的是任意字符
无论是没有字符还是多个字符,他都会匹配
而问号(?)
则是只匹配一个字符串
更多例子
如何匹配以a开头的各种文件?
if exist a*
如何匹配以a开头的txt文本文件?
if exist a*.txt
现在这里有
file1.txt
,file2.aci
,file3.bca
怎么匹配他们?
if exist file?.*
或者
if exist file*
这一块很简单,和其他编程语言一样,我这里就不再累述了
条件判断语句if
IF EXIST filename. (
del filename.
) ELSE (
echo filename. missing.
)
!!! note if条件判断语句语法非常严格
一个空格都不能多的同时一个空格也不能少,下面我们详细看看具体格式
set num=0 //注意,命名变量的时候等号两边不能有空格
//严格注意,if 后面需要接一个空格再接变量,然后等条件结束后要再接一个空格才能打括号
if %num%==0 (
echo weGetIt
) else ( // 同理else语句的前后也都需要有空格
echo nofound
)
如何让我想要的条件反向判断呢?
在需要反向判断的if语句后面加上not即可
set a=6
rem 判断a是否等于5
if not %a%==5 (
echo no equ five
)
ccs
在程序里面,我们需要判断某一个条件是否成立这个时候我们需要让机器自己来判断
dos的if语句也有自己非常严格的要求,尤其是对空格的要求
如果空格的写法错误或者多写少写都会导致程序一闪而过(不执行)
循环控制语句
如何使用一个for循环?你需要用for循环遍历文件!
set /a sum=0
for %%i in (*.txt) do (
echo %%i 文件内容如下:
type %%i
)
set /a sum=sum+1
echo 一共显示了%sum个文件%
上面的一段代码首先设置了一个变量sum来记录文件个数
然后使用%%i变量
作为获取每一个文件名字的方法,遍历所有后缀为txt文本的内容
然后通过type
输出里面的文本内容
!!! note 注意
在for语句里面的变量和其他变量不同,需要使用for语句中的变量需要在变量前面加上%%
,例如%%var
或者%%i
,如果输入%var%
当做正常变量使用的话就会报错
!!! note 关于%%变量命名的规范
当前经过测试,发现了一些奇奇怪怪的错误,%%
后面跟着的变量不能超过1个字符,例如,%%var
就会报错,如果%%v
就不会报错,原因不明,希望了解
for语句的更多参数以及说明
上面的这个便是没有任何参数的for语句,这个语句只会遍历当前文件夹下的文件
但是如果我们需要让for循环遍历所有的子文件夹以及里面的文件呢?
如何让for语句循环一百次?
使用参数
/l
就可以,(0,1,99),其中三个数里面,第一个是起始,第二个是步长,第三个是截止数字
@echo off
for /l %%i in (0,1,99) do (
echo %%i
)
pause
for循环内的变量居然不会自增???
如果你曾经写过这样的代码
@echo off
set /a sum=0
for /r %%i in (*) do (
set /a sum=sum+1
echo %sum%
)
pause
那么你就会发现,你输出的结果会是清一色的0
这究竟是怎么回事?难道说是我代码敲错了?其实你没敲错,这个是批命令本来就是这样,我们的window把整个for循环其实看成了一个语句,既然是一个语句,那么语句内的变量自然就不会记录
同时如果你要是在这个for循环的外面再输出一次sum
你就会发现他的值变成了正常的值
但是这给我们的编程带来了很多麻烦,我们要怎么解决呢?
使用
setlocal enabledelayedexpansion
把setlocal enabledelayedexpansion
加在我们for循环的前面就可以解决
set local enbale delayed expansion 如果英语还过得去的朋友稍微记一下就能记得住
注意,在这个延时解释变量开启
的时候,for循环内部的变量不再使用%sum%
而是使用!sum!
的形式,如果依旧使用%sum%
就会出现意料之外的错误
@echo off
set /a sum=0
setlocal enabledelayedexpansion
for /r %%i in (*) do (
set /a sum=sum+1
echo !sum!
)
pause
这个时候就可以看到我们的变量终于正常了!
如何让for语句只遍历文件夹
使用参数
/d
就可以让for语句只遍历文件夹
for /d %%i in (d:\) do (
echo %%i
)
执行后
可以看到,只输出了文件夹
如何让for语句遍历文件夹下所有的文件(不会显示文件夹的名字)?
使用参数
/r
就可以让for语句只遍历文件夹
for /r %%i in (*) do (
echo %%i
)
输出结果
dos操控文件的一些指令
创建一个文件夹
mkdir 文件夹名字
// 如果想要创建一个多级目录,则需要输入
mkdir /childDir/文件夹名字
切换工作路径
创建好了目录之后,我们可以使用`chdir "文件夹名字"`进入我们需要的文件夹
删除一个文件夹
rmdir "文件夹名字"
可选参数:
/S 除目录本身外,还将删除指定目录下的所有子目录和
文件。用于删除目录树。
/Q 安静模式,带 /S 删除目录树时不要求确认
删除一个文件
del 位置(留空的话就会自动默认当前目录) 文件名字
重命名一个文件
RENAME 原名 新名字
//简写
ren 原名 新名字
复制一个文件(夹)
copy 指定要复制的文件 为新文件指定目录或者文件名
移动文件
move 原路径 新路径
实例内容
由于实例内容过多,于是我新开一个帖子