这个是我所以的dos学习笔记,希望对感兴趣的你有所帮助,如有错误,还望不吝赐教。如果对你有帮助,希望给我点个赞哈,Thanks♪(・ω・)ノ
学习主要还是靠坚持,如果真的觉得学一个知识,就坚持下去;三天打鱼俩天晒网,真的不如躺着歇,刷刷剧,或者玩俩局游戏。。。
window的dos命令学习笔记 一
window的dos命令学习笔记 二
window的dos命令学习笔记 三
window的dos命令学习笔记 四
window的dos命令学习笔记 五
window的dos命令学习笔记 六
window的dos命令学习笔记 七
window的dos命令学习笔记 八— bat文件打包成exe程序(实现脚本加密)
window的dos命令学习笔记 九— bat使用小工具
批处理的一些变量是由操作系统事先定义好的,可以适用于任何批处理,我们称这些特殊的变量为“系统变量”。系统变量有很多个,包括硬件类、操作系统类、文件路径类、系统时间类等。
要查看所有的系统变量,请新打开一个cmd窗口,输入set回车即可。
查看当前window系统的变量。
set
返回的除了path占的多,其他都是=
前面的环境变量的名称,后面是变量的值
,可以理解前面就是key后面是value。电脑里面固定的。
如果批处理中需要使用某个变量,可以使用%变量名%
进行使用。
比如:
对几个比较常用的变量解释如下:
%ALLUSERSPROFILE% 本地 返回“所有用户”配置文件的位置。
%APPDATA% 本地 返回默认情况下应用程序存储数据的位置。
%CD% 本地 返回当前目录字符串。
%CMDCMDLINE% 本地 返回用来启动当前的 Cmd.exe 的准确命令行。
%CMDEXTVERSION% 系统 返回当前的“命令处理程序扩展”的版本号。
%COMPUTERNAME% 系统 返回计算机的名称。
%COMSPEC% 系统 返回命令行解释器可执行程序的准确路径。
%DATE% 系统 返回当前日期。使用与 date /t 命令相同的格式。由 Cmd.exe 生成。有关 date 命令的详细信息,请参阅 Date。
%ERRORLEVEL% 系统 返回上一条命令的错误代码。通常用非零值表示错误。
%HOMEDRIVE% 系统 返回连接到用户主目录的本地工作站驱动器号。基于主目录值而设置。用户主目录是在“本地用户和组”中指定的。
%HOMEPATH% 系统 返回用户主目录的完整路径。基于主目录值而设置。用户主目录是在“本地用户和组”中指定的。
%HOMESHARE% 系统 返回用户的共享主目录的网络路径。基于主目录值而设置。用户主目录是在“本地用户和组”中指定的。
%LOGONSERVER% 本地 返回验证当前登录会话的域控制器的名称。
%NUMBER_OF_PROCESSORS% 系统 指定安装在计算机上的处理器的数目。
%OS% 系统 返回操作系统名称。Windows 2000 显示其操作系统为 Windows_NT。
%PATH% 系统 指定可执行文件的搜索路径。
%PATHEXT% 系统 返回操作系统认为可执行的文件扩展名的列表。
%PROCESSOR_ARCHITECTURE% 系统 返回处理器的芯片体系结构。值:x86 或 IA64基于Itanium
%PROCESSOR_IDENTFIER% 系统 返回处理器说明。
%PROCESSOR_LEVEL% 系统 返回计算机上安装的处理器的型号。
%PROCESSOR_REVISION% 系统 返回处理器的版本号。
%PROMPT% 本地 返回当前解释程序的命令提示符设置。由 Cmd.exe 生成。
%RANDOM% 系统 返回 0 到 32767 之间的任意十进制数字。由 Cmd.exe 生成。
%SYSTEMDRIVE% 系统 返回包含 Windows server operating system 根目录(即系统根目录)的驱动器。
%SYSTEMROOT% 系统 返回 Windows server operating system 根目录的位置。
%TEMP% 和 %TMP% 系统和用户 返回对当前登录用户可用的应用程序所使用的默认临时目录。有些应用程序需要 TEMP,而其他应用程序则需要 TMP。
%TIME% 系统 返回当前时间。使用与 time /t 命令相同的格式。由 Cmd.exe 生成。有关 time 命令的详细信息,请参阅 Time。
%USERDOMAIN% 本地 返回包含用户帐户的域的名称。
%USERNAME% 本地 返回当前登录的用户的名称。
%USERPROFILE% 本地 返回当前用户的配置文件的位置。
%WINDIR% 系统 返回操作系统目录的位置。
编写批处理程序时,用户根据需要自己定义的变量称之为用户变量。用户变量类似于C语言里面的变量,仅仅在定义该变量的程序中有效。
用户变量由set命令定义,这是批处理中非常非常重要的一个操作,从而使set命令成为批处理里面使用频率最高的几个命令之一。
比如:
set aa=123
这里的aa
就可以成为用户变量。也可以理解为除了系统变量剩下的都是用户变量。
前面的学习笔记里面,我们已经看到了如何引用变量,即直接用变量名操作变量,通过"%“或”!“来获取变量的值。其中,只有在for语句里面重复对同一变量多次赋值时才需要使用"!",并且在使用
”!“调用变量时,要首先“启用延迟环境变量扩充”,启动命令为:
SetLocal EnableDelayedExpansion。
另外需要说明的是,“启用延迟环境变量扩充”后,所有的”!“都将被视为“取变量值”的特殊符号,即使用”^!“也不能输出符号”!"。若要输出"!",则需要“停用延迟环境变量扩充”,
命令为:SetLocal DisableDelayedExpansion
提到这里使用!
来替代%
进行变量赋值的时候,有没有想到我们前面学习笔记里,学习for的用法的时候,需要使用!
来代替的。
这里既然替代我就再带着一起巩固一下。
比如第一种:(可不要完全复制,要改地址:e:\000dos)
@echo off
setlocal enabledelayedexpansion
FOR /R e:\000dos %%i IN (*.*) DO (
set dd=%%i
set "dd=!dd:~0,-1!"
echo !dd!
)
SetLocal DisableDelayedExpansion
pause
exit
执行效果:
这个都是我dos学习时的笔记文件。
如果我们不替换,看看是什么效果:
@echo off
::setlocal enabledelayedexpansion
FOR /R e:\000dos %%i IN (*.*) DO (
set aa=%%i
echo %aa%
)
::SetLocal DisableDelayedExpansion
pause
exit
不知道为什么结果是这样,然后我就好奇,寻找是不是替换之前就有问题呐?
第三个代码:
@echo off
::setlocal enabledelayedexpansion
FOR /R e:\000dos %%i IN (*.*) DO (
echo %%i
)
::SetLocal DisableDelayedExpansion
pause
exit
可以看出,第三个代码和第二个代码的区别,就是中间没有了一个赋值,肯定赋值的地方出了问题。
至此我们就应该理解下面这句话了:
其中,只有在for语句里面重复对同一变量多次赋值时才需要使用"!",并且在使用"!"
调用变量时,要首先“启用延迟环境变量扩充”,启动命令为:SetLocal EnableDelayedExpansion
。
其实这个地方就是需要使用
setlocal enabledelayedexpansion
中间可以加入for循环逻辑语句。
SetLocal DisableDelayedExpansion
需要理解点:
!
替换%
生效,不然报错。!
不能多次对一个变量多次赋值,当然goto
除外,因为之前我们使用goto
的时候,是可以多次赋值的。(这个赋值应该只限于for语句中吧,这个属于小编猜测,具体还不确定)%%i
不知道for语句中你们看到上面代码有没有疑惑,不是应该是%i么?其实我之前也有这个疑问,刚刚又看到,加上昨天学习了转义,我感觉就是因为转义的问题。直接传递参数,即在使用call命令时,不使用任何参数,在子函数或子批处理里面直接对主函数(也称父批处理)里面的变量进行修改。就相当于python的函数中加入global,然后都外部的变量进行修改,最后函数执行完毕影响外部的变量。
直接传递参数举例:
@echo off
setlocal enabledelayedexpansion
set var=aCdehiM,?mnrstW y
echo %var%
call :deal
setlocal disabledelayedexpansion
set var=%var:?=!%
echo %var%
pause>nul
exit
:deal
set tm=!var!
set var=
for %%i in (6,3,11,11,16,15,1,4,11,5,12,13,9,0,12,7,15,14,5,10,2,16,18,8) do (
set var=!var!!tm:~%%i,1!
)
goto :eof
上面的代码涉及到函数,变量的多次赋值,可以发现,当我们把变量var作为参数赋予子函数:deal后,子函数对var的值进行了修改;当子函数返回后,主函数里面的var的值就已经是子函数里面var被修改后的值了。
函数执行完毕后,又可以对变量var进行一个字符串的替换操作。
间接传递参数,即在使用call命令时,在其后面添加参数,形如call {[:label][ChildBatch]} Parameter1 Parameter2 ... ParameterN
。这跟python或者其他语言里面传递参数的格式类似。不同于python语言,批处理中的子函数不需要定义形参,更不需要指定参数的个数。传递过来的参数,在子函数或子批处理里面是以%1~%9
的形式表示的,即%1~%9
分别表示传递过来的第1~9
个参数。%*
代表除了%0
(%0
是当前执行的bat脚本文件地址)的所有参数。
例子:
@echo off
call :deal aaa bbb "c c" ddd eee
pause>nul
exit
:deal
echo %%0 = %0
echo %%1 = %1
echo %%2 = %2
echo %%3 = %3
echo %%4 = %4
echo %%5 = %5
通过这个例子就可以清晰的看到%n
参数表示法的用法。参数列表中包含空格的依旧要用双引号(")引起来;另外,也可以看到,%0已经变成了子函数的标号了,而不是父批处理的文件名全称。
既然上面又提到for语句了,我这里想对for做些总结,也算是复习巩固一下吧。
%%i
从上面的例子中,可以发现,在cmd环境中执行for循环目录时,只能用单个%
来代表。
但是在bat文件中必须要用%%i
来表示cmd中的%i
,我感觉就是因为转义的问题,昨天的学习笔记中,我们学习了转义问题,发现除了%%
转义成%
,这一个特殊外,其余在bat文件中都需要使用^
来转义后面的字符。
/d
参数:语法格式:
FOR /D %i IN (参数) DO @echo %i
/d
参数的意思我现在才更懂了一点,学习就是这样嘛,慢慢的学,不能一下子学到什么都理解的样子(除非俩种可能:①你是天才,这方面有天赋;②是你学的知识本来就简单,很多人一看也懂
)
/d
在for循环中,就遍历当面目录或者指定目录下,循环匹配到的文件夹,不匹配文件。
其实上面语法中的参数
有一下几种:
E:\000dos>FOR /D %i IN (e:\000dos\*) DO @echo %i
e:\000dos\1笔记一
e:\000dos\2笔记二
e:\000dos\3笔记三
e:\000dos\4笔记四
e:\000dos\5笔记五
e:\000dos\6笔记六
其中这里的*代表所有字符,长度不限。
顺便把?
也讲解一下吧,一个问号代表一个任意字符,
E:\000dos>FOR /D %i IN (e:\000dos\1???) DO @echo %i
e:\000dos\1笔记一
代码中我的三个???
就是代表匹配到的笔记一
三个字符。
*
号表示:E:\000dos>FOR /D %i IN (*) DO @echo %i
1笔记一
2笔记二
3笔记三
4笔记四
5笔记五
6笔记六
这里执行之后会把当前的所有目录匹配到,位置是当前执行的目录。
比如:
E:\000dos\4笔记四>FOR /D %i IN (*) DO @echo %i
demo1
?
表示E:\000dos>FOR /D %i IN (????) DO @echo %i
1笔记一
2笔记二
3笔记三
4笔记四
5笔记五
6笔记六
E:\000dos>FOR /D %i IN (??????????) DO @echo %i
12demo
13demo
14demo
1笔记一
2笔记二
3笔记三
4笔记四
5笔记五
6笔记六
从上面的?
号的数量可以看出,匹配到的文件夹名称的字符长度可以比?
的长度少,但是不能多。
字符
+*
+?
表示:测试代码:
E:\000dos>FOR /D %i IN (13*) DO @echo %i
13demo
E:\000dos>FOR /D %i IN (1?demo) DO @echo %i
12demo
13demo
14demo
看了上面的这个,只是匹配当前的地址下的文件夹,却不能匹配文件,如何匹配一个目录下文件呐,也不进入子目录?
其实也简单,不带参数就好了,自己写几个代码测试测试就懂了:
下面俩个代码时我测试可以匹配当前目录的所有文件,如果需要一些条件筛选匹配,自己根据上面的*
、?
、字符
灵活使用进行匹配吧。
E:\000dos>FOR %i IN (*.*) DO @echo %i
cd_help.txt
del_help.txt
for1.txt
for_help.txt
name.txt
start_help.txt
保留命令帮助文档.bat
当前目录打开cmd.bat
E:\000dos>FOR %i IN (*) DO @echo %i
cd_help.txt
del_help.txt
for1.txt
for_help.txt
name.txt
start_help.txt
保留命令帮助文档.bat
当前目录打开cmd.bat
语法结构:
FOR /R [[drive:]path] %variable IN (set) DO command [command-parameters]
其实这个/r 参数就是进入当前目录或者给定目录的目录树(子目录也进入匹配)。
*
和*.*
:经过测试发现,*
和*.*
都是匹配目录树的文件的,如果需要固定名称,可以自己根据需要结合:*
、?
、字符
灵活使用进行匹配。
E:\000dos>FOR /r %i IN (*) DO @echo %i
E:\000dos\cd_help.txt
E:\000dos\del_help.txt
E:\000dos\for1.txt
E:\000dos\for_help.txt
E:\000dos\name.txt
E:\000dos\start_help.txt
E:\000dos\保留命令帮助文档.bat
E:\000dos\当前目录打开cmd.bat
E:\000dos\1笔记一\10set.bat
E:\000dos\1笔记一\1hello.bat
这里我只复制了前面几个结果,看懂就行了。
E:\000dos>FOR /r %i IN (*.*) DO @echo %i
E:\000dos\cd_help.txt
E:\000dos\del_help.txt
E:\000dos\for1.txt
E:\000dos\for_help.txt
E:\000dos\name.txt
E:\000dos\start_help.txt
E:\000dos\保留命令帮助文档.bat
.
经过测试发现,在/r目录树下,.
就代表匹配目录(文件夹)
E:\000dos>FOR /r %i IN (.) DO @echo %i
E:\000dos\.
E:\000dos\12demo\.
E:\000dos\13demo\.
E:\000dos\14demo\.
E:\000dos\1笔记一\.
E:\000dos\1笔记一\444\.
E:\000dos\1笔记一\444\111\.
E:\000dos\2笔记二\.
E:\000dos\3笔记三\.
E:\000dos\4笔记四\.
E:\000dos\4笔记四\demo1\.
E:\000dos\4笔记四\demo1\deep2\.
E:\000dos\5笔记五\.
E:\000dos\6笔记六\.
把需要匹配的目录放在参数/r
后面即可。
示例代码:
E:\000dos>FOR /r E:\000dos\4笔记四 %i IN (.) DO @echo %i
E:\000dos\4笔记四\.
E:\000dos\4笔记四\demo1\.
E:\000dos\4笔记四\demo1\deep2\.
这个地方比较好理解,和其他语言的用法类似。
FOR /L %%variable IN (start,step,end) DO command
1、其中,start为开始计数的初始值,step为每次递增的值,end为结束值。当end小于start时,step需要设置为负数。
2、该集表示以增量形式从开始到结束的一个数字序列。因此,(1,1,5)将产生序列 1 2 3 4 5,(5,-1,1)将产生序列(5 4 3 2 1)
打印出10以内的奇数:
E:\000dos>echo off
for /l %i in (1,2,10) do echo %i
1
3
5
7
9
FOR /F ["options"] %%variable IN (set) DO command
其中,set为(“string”、‘command’、file-set)中的一个;options是(eol=c、skip=n、delims=xxx、tokens=x,y,m-n、usebackq)中的一个或多个的组合。各选项的意义参见for /f。一般情况下,使用较多的是
skip、tokens、delims
三个选项。
新建一个demo1.txt文件,查看内容:
e:\000dos\6笔记六>type demo1.txt
2019/12/19 16:31 <DIR> .
2019/12/19 16:31 <DIR> ..
2019/12/19 16:27 173 1!.bat
2019/12/19 16:33 157 2.bat
2019/12/19 16:21 152 3.bat
2019/12/19 16:35 143 4.bat
4 个文件 625 字节
2 个目录 35,105,640,448 可用字节
tokens=*
options为"tokens=*"
时表示读取每一行
e:\000dos\6笔记六>for /f "tokens=*" %i in (demo1.txt) do @echo %i
2019/12/19 16:31 <DIR> .
2019/12/19 16:31 <DIR> ..
2019/12/19 16:27 173 1!.bat
2019/12/19 16:33 157 2.bat
2019/12/19 16:21 152 3.bat
2019/12/19 16:35 143 4.bat
4 个文件 625 字节
2 个目录 35,105,640,448 可用字节
tokens=1
options为"tokens=1"
或者不写参数时
表示读取每一行的第一列,默认情况下,分隔符为空格和制表符(tab键)
e:\000dos\6笔记六>for /f "tokens=1" %i in (demo1.txt) do @echo %i
2019/12/19
2019/12/19
2019/12/19
2019/12/19
2019/12/19
2019/12/19
4
2
e:\000dos\6笔记六>for /f %i in (demo1.txt) do @echo %i
2019/12/19
2019/12/19
2019/12/19
2019/12/19
2019/12/19
2019/12/19
4
2
skip=2
options为"skip=2 tokens=*"
表示跳过前2行,读取之后的每一行。
e:\000dos\6笔记六>for /f "skip=2 tokens=*" %i in (demo1.txt) do @echo %i
2019/12/19 16:27 173 1!.bat
2019/12/19 16:33 157 2.bat
2019/12/19 16:21 152 3.bat
2019/12/19 16:35 143 4.bat
4 个文件 625 字节
2 个目录 35,105,640,448 可用字节
如果"skip=2 tokens=3"
则表示跳过前2行,读取后面的每行的第三列。
e:\000dos\6笔记六>for /f "skip=2 tokens=3" %i in (demo1.txt) do @echo %i
173
157
152
143
625
35,105,640,448
"skip=2 tokens=2 delims=/"
代表的是跳过前俩行,分隔符为/,读取后面每行的第二列。
e:\000dos\6笔记六>for /f "skip=2 tokens=2 delims=/" %i in (demo1.txt) do @echo %i
12
12
12
12
从上周开始学到现在,发现dos命令,最重要的有这么几个命令:
set、for和if。
感觉这几个比较难掌握,只能没事时多看多敲点代码,多些几个小脚本熟练熟练了。