欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

window的dos命令学习笔记 五

程序员文章站 2022-04-24 07:53:47
...

一、dos历史学习笔记

window的dos命令学习笔记 一

window的dos命令学习笔记 二

window的dos命令学习笔记 三

window的dos命令学习笔记 四

二、函数:

这里我补充一个dos函数的格式和用法,不然后面的可能用到函数的地方理解不了,而且函数也是常用的。
为了学习这个函数,我这里找了俩个有关dos的函数博客,大家学习可以参考参考。
如果看了人家的博客,觉得对你有帮助,记得给人家点个赞,也算是对原创作者的一个鼓励(我已经偷偷点赞了,比较看懂了一些dos函数的知识)。
博客一
博客二

0、一些特殊字符的转义:

因为下面的的内容涉及的一些内容,如果这里不说一下一些转义字符,会耽误太多时间,我也是自己耽误时间之后,搜索了许久找到一个博客总结的还不错,博客地址,因为下面的内容中有个%%0我没有看懂,但是结果就是输出%0,意思是俩个%%转义成一个%,所以搜索许久找到。
我这里手动把作者的整理的转义敲过吧。

期望得到的字符 转义前字符(代码中的字符)
% %%
^ ^^
& ^&
> ^>
| ^|
^’
` ^`
, ^,
; ^;
= ^=
( ^(
) ^)
! ^^!
\ ^\
[ ^[
] ^]
" ^"

通过测试,我发先什么作者的有些问题,我把他们更改为正确的,最后突然发现,除了%%转义成%,其他都是前加上^进行转义。
我的测试代码:

@echo off
set aa=C:\Windows\PPP\a.btx
call :deal aaa %aa% "c c" ddd eee
pause>nul
exit

:deal
echo %%0 =
timeout 1
echo ^^ =
timeout 1
echo ^& =
timeout 1
::echo ^<</code> =
timeout 1
echo ^> =
timeout 1
echo ^| =
timeout 1 
echo ^' =
timeout 1 
echo ^` =
timeout 1 
echo ^, =
timeout 1 
echo ^; =
timeout 1 
echo ^= = 
timeout 1
echo ^( = 
timeout 1
echo ^) =
timeout 1 
echo ^! = 
timeout 1
echo 原先的:\\ =
echo ^\ =
timeout 1 
echo 原先的:\[ =
echo ^[ = 
timeout 1
echo 原先的:\] =
echo ^] = 
timeout 1
echo 原先的:\" =
echo ^" =
timeout 1 
goto:eof

注意点:
rem::(英文双引号)都注释的作用

这几个错误的地方(可能之前能用吧,不过现在是需要^进行转义):
window的dos命令学习笔记 五

1、dos函数的结构

这里我只写入一些主要内容吧,想详细看的去看看上面俩篇博客。

:myDosFunc    - 函数的开始,用一个标签标识(可以理解为函数名)
函数体(写入函数逻辑)
GOTO:EOF 函数结束,固定,可以使用小写

2、批处理文件中执行函数:

call :myDosFunc    其实call是执行批处理文件的,myDosFunc可以理解为函数名。

3、传递参数:

这个我是在作者中的代码修改的。注释我写在每一行了,这里不过多介绍了。

@echo off
:: 空格分隔
call:myDosFunc 100 YeePEE
:: 空格分隔
call:myDosFunc 100 "for me"
:: 逗号分隔
call:myDosFunc 100,"for me"
:: 逗号+空格分隔
call:myDosFunc 100,for me
:: tab键分隔
call:myDosFunc 100	for	me
:: 空格键+tab键分隔
call:myDosFunc 100 for	me
echo.&pause&goto:eof

:myDosFunc    

echo 参数1: %1 参数2: %2 参数3: %3 参数4: %4
goto:eof

运行结果:
window的dos命令学习笔记 五

小结:

总传参的结果可以看到,call执行批处理文件或者函数的时候,可以使用逗号空格tab键三种分开传递,而且可以同时使用。

4、全局变量和局部变量的区别:

函数中,不做任何操作,如果直接使用外面全局的变量名,进行赋值等操作,会改变全局变量的最终结果。

@echo off

set aa=123

call :fun1 %aa%

echo %aa%
pause
:fun1
echo 函数名:%0
echo 参数1:%1
set aa=456
goto:eof

运行结果,可以看出,外面的全局变量aa在函数中被更改了。
window的dos命令学习笔记 五

函数的局部变量:

函数的局部变量
局部变量放在SETLOCAL与ENDLOCAL之间定义。
SETLOCAL可以很好的保护函数内与外面的变量不会冲突。即:

setlocal
set aa=456
endlocal

比如,我上面的代码进行更改:

@echo off

set aa=123

call :fun1 %aa%

echo %aa%
pause
:fun1
echo 函数名:%0
echo 参数1:%1
setlocal
set aa=456
endlocal
goto:eof

执行结果:
window的dos命令学习笔记 五
从结果来看,发现局部变量的定义已经无法影响外部的全局变量了。

5、函数的返回值:

这里我直接引用原作者的内容了。

1、直接函数内部改变全局变量

其实这个,我们前面有个测试局部变量的时候已经用到了。可以直接在函数内部修改全局变量。

修改完善的代码:

set "var1=some hopefully not important string"
echo var1 之前是: %var1%
call:myGetFunc
echo var1 之后是 : %var1%

:myGetFunc
set "var1=DosTips"
goto:eof

运行结果:
window的dos命令学习笔记 五

2、我感觉作者的第二个和第一个一样吧

我感觉作者的第二个和第一个一样吧,只不过把外部的全局变量的名称作为参数传入函数内部,在进行更改,和不传入参数,直接修改变量名的是一样的,下面是我根据作者的函数博客进行修改的。

@echo off
set "var1=CmdTips"
echo var1 before: %var1%

call:myGetFunc var1
::call:myGetFunc %var1%
echo var1 after : %var1%
pause

:myGetFunc   
echo %1
echo %%1%
set "%1=DosTips"
goto:eof

运行结果:
window的dos命令学习笔记 五

三、字符串的一些操作

在批处理中,set的功能有点繁杂:设置变量、显示环境变量的名及值、做算术运算、等待用户的输入、字符串截取、替换字符串,是我们常用的命令之一。

1、截取字符串

在字符串截取方面,新手因为没能注意到偏移量的问题,很容易提取到错误的字符串,因此,这里,详细解释 set 截取字符的用法。

我们先来看一个例子:

set str=123456789

现在,我需要提取变量 str 中的第一个字符,那么,该怎么写命令呢?

set var=%str:~1,1%?我想,这很可能是很多粗懂set用法的新手们的第一反应,实际上,这条语句提取到的是字符"2",并不是我们想要的"1",也就是说,set var=%str:~1,1% 提取到的是字符串第二位上的字符,而不是第一位上的,这是什么原因呢?

现在,我们可以把截取字符的命令用一条语句模式来表示,那就是:set var=%str:~偏移量,长度%。(其实懂python的可以这样理解,偏移量的数值就是对于字符串的下标,只不过下标是从0开始,后面的长度就是指从下标开始要几个字符)
下面我截图一个代码就懂了,可以自己敲一下懂明白了。

window的dos命令学习笔记 五
到目前为止,我们只谈到了很简单的截取操作,如果碰到比较复杂的提取需求,比如:提取第2个字符及其之后的所有字符、提取最后的3个字符、提取倒数第 2个及其之前的3个字符、提取除了最后4个字符的字符串……那又该怎么办呢?别着急,set 命令在设计的时候就已经充分考虑到我们的复杂需求,只要对刚才我们提到的字符截取语句稍做改动,就可以很轻松地完成任务。

我们知道,数字的正负可以用+-符号来表示,同样的,方向的正反也可以用±来标注。在 set 做字符截取的时候,引入了+-符号来表示字符截取的方向:从左到右截取为+,从右到左截取为-,所以,

set var=%str:~1,4%

也可以写成

 set var=%str:~+1,+4% 

只是在从右到左截取的时候,情况发生了一点变化,那就是:偏移量的起点以整个字符串最后一个字符的后一位来计算。现在,我们可以来回答上一段中提出的一些问题:

提取最后的3个字符:

set var=%str:~-3%

提取倒数第2个及其之前的3个字符:

set var=%str:~-5,4%

提取除了最后4个字符的字符串:

set var=%str:~0,-4%

提取最后四位:

set var=%str:~-4,4%

set var=%str:~偏移量,长度% 这样的语句中,如果没有逗号及其之后的长度,就表示截取偏移量位置上及其之后的所有字符;如果长度的值为负数,则表示抛弃最后几个字符。

假设 set str=123456789

现在,我们可以对任意位置上的字符做提取工作了(假设 set str=123456789):

① 提取1

set str=123456789
set var=%str:~0,1% 或 set var=%str:~0,-8% 或 set var=%str:~-9,1%

window的dos命令学习笔记 五

② 提取2

set str=123456789
set var=%str:~1,1% 或 set var=%str:~1,-7% 或 set var=%str:~-8,1%

window的dos命令学习笔记 五

③ 提取9

set str=123456789
set var=%str:~8,1% 或 set var=%str:~8% 或 set var=%str:~-1,1% 或 set var=%str:~-1%

window的dos命令学习笔记 五

④ 提取123

set str=123456789
set var=%str:~0,3% 或 set var=%str:~0,-6% 或 set var=%str:~-9,3%

window的dos命令学习笔记 五

⑤ 提取234

set str=123456789
set var=%str:~1,3% 或 set var=%str:~1,-5% 或 set var=%str:~-8,3%

window的dos命令学习笔记 五

⑥ 提取789

set str=123456789
set var=%str:~6,3% 或 set var=%str:~6% 或 set var=%str:~-3,3% 或 set var=%str:~-3%

window的dos命令学习笔记 五

总结:

最后,我们来总结一下字符截取的规律:

①、替换字符串格式

set str=123456789
set var=%str:~数值1,数值1% 

说明:

  1. 截取字符串可以用 set var=%str:~数值1,数值2% 这样的语句来实现;
  2. 字符的截取是以偏移量(也可以理解为下标)来计算的,而不是以字符的绝对位置来计算;
  3. 数值1为正数时,表示从左到右截取;当数值1为负数时,表示从右到左截取;
  4. 数值2为正数时,表示要截取后字符串的长度;当为负数时,表示要抛弃的最后几个字符长度;
  5. 数值2及其之前的逗号不存在时,表示截取的是第(数值1+1)个字符及其之后的所有字符;

截取字符串可以说是字符串处理功能中最常用的一个子功能了,能够实现截取字符串中的特定位置的一个或多个字符。

举例说明其基本功能:

代码:

@echo off
set ifo=abcdefghijklmnopqrstuvwxyz0123456789
echo 原字符串(第二行为各字符的序号):
echo %ifo%
echo 123456789012345678901234567890123456
echo 截取前5个字符:
echo      %ifo:~0,5%
echo 截取最后5个字符:
echo      %ifo:~-5%
echo 截取第一个到倒数第6个字符:
echo      %ifo:~0,-5%
echo 从第4个字符开始,截取5个字符:
echo      %ifo:~3,5%
echo 从倒数第14个字符开始,截取5个字符:
echo      %ifo:~-14,5%
pause

window的dos命令学习笔记 五

当然,上面的例子只是将字符串处理的基本功能展示出来了,还看不出字符串处理具体有什么用处。下面这个例子是对时间进行处理。

@echo off
echo 当前时间是:%time% 即 %time:~0,2%点%time:~3,2%分%time:~6,2%秒%time:~9,2%厘秒
pause

执行效果:

window的dos命令学习笔记 五

2、替换字符串

替换字符串,即将某一字符串中的特定字符或字符串替换为给定的字符串,这个比较简单。

举例说明其功能:

@echo off
set aa=伟大的中国!我为你自豪!
echo 替换前:%aa%
echo 替换后:%aa:中国=*%
echo aa = %aa%
set "aa=%aa:中国=*%"
echo aa = %aa%
pause

单个步骤讲解:
window的dos命令学习笔记 五
对于上面的例子有一点说明,对比两个echo aa = %aa%可以发现,如果要修改变量aa的内容的话,就需要将修改结果“%aa:中国=*%”赋值给变量aa。上面的字符串截取也有着同样的特点。

总结:

window的dos命令学习笔记 五

set aa=字符串的使用,字符串的剪切,字符串的替换。
set aa=%aa:字符串=str%
echo %aa%

有上面的代码可以知道,字符串的替换就是把变量(例子的指aa),set aa=%aa:字符串=str%中的字符串,就是需要替换的字符串,后面的str就行需要最后替换成功的字符串,返回的就是结果,如果aa含有多个需要替换的,会全部被替换。

3、字符串合并:

其实,合并字符串就是将两个字符串放在一起就可以了。这个看一下自己敲一遍就懂了。
举例说明:

@echo off
set aa=伟大的中国!
set bb=我为你自豪!
echo %aa%%bb%
echo aa=%aa%
echo bb=%bb%
set "aa=%aa%%bb%"
echo aa=%aa%
pause

执行结果,
window的dos命令学习笔记 五
同样,如果要改变变量aa的内容的话,就需要将合并结果“%aa%%bb%”赋值给变量aa。

window的dos命令学习笔记 五

4、扩充字符串(其实就是获取文件的磁盘、目录、创建时间,文件名、后缀等信息)

“扩充”这个词汇来自于微软自己的翻译,意思就是对表示文件路径的字符串进行特殊的处理,具体功能罗列如下:

这个呐,是for的帮助文档里面的,cmd中输入 for /? 最后面即可看到。

    另外,FOR 变量参照的替换已被增强。你现在可以使用下列
选项语法:

     %~I          - 删除任何引号("),扩展 %I
     %~fI        - 将 %I 扩展到一个完全合格的路径名
     %~dI        - 仅将 %I 扩展到一个驱动器号
     %~pI        - 仅将 %I 扩展到一个路径
     %~nI        - 仅将 %I 扩展到一个文件名
     %~xI        - 仅将 %I 扩展到一个文件扩展名
     %~sI        - 扩展的路径只含有短名
     %~aI        - 将 %I 扩展到文件的文件属性
     %~tI        - 将 %I 扩展到文件的日期/时间
     %~zI        - 将 %I 扩展到文件的大小
     %~$PATH:I   - 查找列在路径环境变量的目录,并将 %I 扩展
                   到找到的第一个完全合格的名称。如果环境变量名
                   未被定义,或者没有找到文件,此组合键会扩展到
                   空字符串

可以组合修饰符来得到多重结果:

     %~dpI       - 仅将 %I 扩展到一个驱动器号和路径
     %~nxI       - 仅将 %I 扩展到一个文件名和扩展名
     %~fsI       - 仅将 %I 扩展到一个带有短名的完整路径名
     %~dp$PATH:I - 搜索列在路径环境变量的目录,并将 %I 扩展
                   到找到的第一个驱动器号和路径。
     %~ftzaI     - 将 %I 扩展到类似输出线路的 DIR

在以上例子中,%I 和 PATH 可用其他有效数值代替。%~ 语法
用一个有效的 FOR 变量名终止。选取类似 %I 的大写变量名
比较易读,而且避免与不分大小写的组合键混淆。

昨天学习笔记的最后一个查询文件名,就是其中的一个语法。获取文件名就是这个%~nI - 仅将 %I 扩展到一个文件名

以上内容引用于for /?帮助信息。其中的I代表变量I,不过需要说明的是,不是所有的变量都能够进行扩充的,有两个条件:

  1. 该字符串代表一个文件路径;
  2. 变量要用%x来表示,x可取a-z A-Z 0-9共62个字符中的任意一个。举例说明:
@echo off
echo 正在运行的这个批处理:
echo 完全路径:%0
echo 去掉引号:%~0
echo 所在分区:%~d0
echo 所处路径:%~p0
echo 文件名:%~n0
echo 扩展名:%~x0
echo 文件属性:%~a0
echo 修改时间:%~t0
echo 文件大小:%~z0
pause

执行结果:
window的dos命令学习笔记 五

其中代码中的%0就是批处理传入的参数,这个是第一个学习笔记的内容,%0代表文件本身,后面的%1- %n代表第1-n个传入的参数。

@echo off
set aa=C:\Windows\PPP\a.btx
call :deal aaa %aa% "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

window的dos命令学习笔记 五

其中,变量aa在之前是不可以扩充的,通过call命令并将aa作为参数传递给子函数:deal,将aa变量转换成了变量%1,即符合%x格式,从而可以进行字符串扩充。
至于%x中x取a-z A-Z的形式,可以复习一下for语句,for语句里面的变量就是用%x来表示的,因而可以直接进行扩充。

5、数值计算

批处理里面的数值计算功能较弱,只能够进行整型计算,忽略浮点数的小数部分;同时数值计算的范围也受限于系统位数。

数值计算需要使用set命令,具体格式为“set /a expression”。其中,expression代表计算表达式,计算表达式跟C语言里面的表达式基本上完全一致。set支持的运算符也跟C语言里面的一样,只是没有了増一减一。
set支持的运算符及优先级排序如下:

并以递减的优先权顺序支持下列操作:

    ()                  - 分组
    ! ~ -               - 一元运算符
    * / %               - 算数运算符
    + -                 - 算数运算符
    << >>               - 逻辑移位
    &                   - 按位“与”
    ^                   - 按位“异”
    |                   - 按位“或”
    = *= /= %= += -=    - 赋值
      &= ^= |= <<= >>=
    ,                   - 表达式分隔符

如果你使用任何逻辑或取余操作符, 你需要将表达式字符串用引号扩起来。在表达式中的任何非数字字符串键作为环境变量名称,这些环境变量名称的值已在使用前转换成数字。如果指定了一个环境变量名称,但未在当前环境中定义,那么值将被定为
零。这使你可以使用环境变量值做计算而不用键入那些 % 符号来得到它们的值。如果 SET /A 在命令脚本外的命令行执行的,那么它显示该表达式的最后值。该分配的操作符在分配的操作符
左边需要一个环境变量名称。除十六进制有 0x 前缀,八进制
有 0 前缀的,数字值为十进位数字。因此,0x12 与 18 和 022
相同。请注意八进制公式可能很容易搞混: 08 和 09 是无效的数字,
因为 8 和 9 不是有效的八进制位数。(& )

写个简单的循环10次:

@echo off

set a=0

:add
set /a a=%a%+1

echo %a%
if %a% leq 10 goto add
pause

window的dos命令学习笔记 五

四、总结set

今天又学了一些字符串的操作之后,发现dos的set命令真的很强大,目前学到的功能还不少。看来比我当前学到时认为的还要重要的。

目前的功能:

  1. 设置变量:set aa=123
  2. 执行表达式:set /a 运算逻辑(加减乘除等操作)
  3. input接入输入:set /p b=请输入内容
  4. 字符串截取(剪切):详情看面的截取总结吧。
set str=123456789
set var=%str:~数值1,数值1% 
  1. 字符串合并(其实这个就是字符串拼接,和功能1和变量传递一样。)

目前我学的的关于set就这么多了,不知道后续还会不会给我惊喜。

相关标签: dos命令