批处理BAT脚本中set命令的使用详解(批处理之家Batcher)

目录
  • 一、使用 set 命令进行赋值
    • 1、等号两边不要有空格
    • 2、变量值包含特殊字符需用双引号
    • 3、避免使用系统环境变量同名的自定义变量
    • 4、语法可行但不推荐使用
  • 二、使用 set /p 命令读取输入
  • 三、使用 set /a 命令进行数学运算(1)
  • 四、使用 set /a 命令进行数学运算(2)
  • 五、使用 set 命令进行字符串截取
  • 六、使用 set 命令进行字符串替换
  • 七、set命令知识点(1)把命令结果赋值给变量
  • 八、set命令知识点(2)显示以某字符开头的变量

一、使用 set 命令进行赋值

SET [variable=[string]]

1、等号两边不要有空格

正确写法

C:\>set str=ScriptHome
C:\>echo %str%
ScriptHome

错误写法

C:\>set str = ScriptHome
C:\>echo %str%
%str%

2、变量值包含特殊字符需用双引号

正确写法

C:\>set "str=Bat&Home"
C:\>echo "%str%"
"Bat&Home"

错误写法

C:\>set str=Bat&Home
'Home' 不是内部或外部命令,也
不是可运行的程序或批处理文件。
C:\>echo "%str%"
"Bat"

变量值设置为空可以清空变量值,实现变量初始化。

3、避免使用系统环境变量同名的自定义变量

例如:

path , date , errorlevel 等

4、语法可行但不推荐使用

使用连等把多个变量赋值成数字 set /a x=y=100
逗号分隔把多个变量赋值成数字 set /a x=1,y=2

上面是dos界面下的写法,下面是批处理中的写法,主意是变量

示例1:

显示所有的变量的值

@echo off
set
pause  

示例2:

@echo off
set var=我是值
echo %var%
pause 

请看 set var=我是值 ,这就是BAT直接在批处理中设置变量的方法!
set 是命令 var是变量名 =号右边的"我是值"是变量的值
在批处理中我们要引用这个变量就把var变量名用两个%(百分号)扩起来,如%var%

二、使用 set /p 命令读取输入

交互获取用户输入

@echo off
set /p input=请输入一个字符串:
echo,%input%
pause

读取文件的第一行内容

C:\>echo BatHome>1.txt
C:\>set /p input=<"1.txt"
C:\>echo %input%
BatHome

输出字符串之后不产生换行

@echo off
for %%i in (bat home) do (
echo,%%i
)
pause

输出

bat
home
请按任意键继续. . .

@echo off
for %%i in (bat home) do (
set /p =%%i<nul
)
pause

输出

bathome请按任意键继续. . .

批处理光标回退(非cls清屏)动画效果演示

@echo off
echo bbs.bathome.net
set /p =光标回退(非cls清屏)动画效果演示:<nul
for /l %%i in (1,1,10) do (
    set /p =%%i<nul
    set /p =<nul
    ping -n 2 127.1 >nul
)
echo,
pause

三、使用 set /a 命令进行数学运算(1)

等号右侧的变量可以省略百分号

C:\>set x=1
C:\>set y=2
C:\>set /a n=%x%+%y%

3

C:\>set x=1
C:\>set y=2
C:\>set /a n=x+y

3

八进制和十六进制转换成十进制很简单

C:\>set /a 012

10

C:\>set /a 0xA
10

BAT文件里面进行“取余”操作的时候需要使用两个百分号

@echo off
set /a n=3%%2
echo %n%
pause

逻辑运算的特殊字符需要使用双引号

@echo off
set /a "m=1<<10"
set /a n=1"<<"10
echo %m% %n%
pause

四、使用 set /a 命令进行数学运算(2)

 不支持直接计算超大数(例如磁盘空间的计算)

C:\>set /a n=2147483646+1
2147483647
C:\>set /a n=2147483647+1
-2147483648
C:\>set /a n=2147483648+1

无效数字。数字精确度限为 32 位。

C:\>set /a n=-2147483646-1 -2147483647
C:\>set /a n=-2147483647-1 -2147483648
C:\>set /a n=-2147483648-1
无效数字。数字精确度限为 32 位。

不支持直接计算浮点数

批处理通过自己编写算法实现浮点计算

题目:

输入任意两个小数(小数点后最多为两位数),通过批处理输出两数的和、差、积、商
(积、商均保留两位小数)

@echo off&setlocal enabledelayedexpansion
set /p str=输入的两数为:
set /a num_1=0,num_2=0,num=1,v=0
for %%a in (%str%) do (
    set /a n+=1
    for /f "tokens=1,2 delims=." %%b in ("%%a") do (
        set "_!n!=%%b"
        if "%%c" equ "" (
           set ".!n!=00"&set /a m+=1
           if !m! equ 2 set "flag=a"
           ) else (
           set "a=%%c00"&set "a=!a:~,2!"
           set ".!n!=!a!"
        )
     )
)
for %%a in (+#h -#c) do (
    for /f "tokens=1,2 delims=#" %%b in ("%%a") do (
        if "%_1:~,1%" equ "-" set "k1=-"
        if "%_2:~,1%" equ "-" set "k2=-"
        set /a %%c1=_1%%b_2,%%c2=!k1!1%.1%%%100%%b!k2!1%.2%%%100
        if !%%c1! lss 0 (
           if !%%c2! leq -100 set /a %%c2+=100,%%c1-=1
           ) else (
           if !%%c1! equ 0 (
              if !%%c2! lss 0 set "%%c1=-0"&set "a=!%%c2!"&set "%%c2=!a:-=!"
              ) else (
              if !%%c2! lss 0 set /a %%c2+=100,%%c1-=1
           )
         )
         if !%%c2! geq 100 set /a %%c2-=100,%%c1+=1
    )
)
for %%a in (h2 c2) do (
    set "a=!%%a!"&set "a=!a:-=!"&set %%a=!a!
    if !a! lss 10 set "%%a=0!a!"
)
echo 其和为:%h1%.%h2%&echo 其差为:%c1%.%c2%&set /a n=0
if defined flag set ".1="&set ".2="
for %%a in (1 2) do (
    if "!_%%a!" equ "0" (
       set "_%%a="&set /a .%%a=1!.%%a!%%100
       ) else (
       if "!_%%a!" equ "-0" (
          set "_%%a=-"
          ) else (
          set "a=!_%%a!"&set "a=!a:-=!"
          set /a n+=1&call :lp
       )
    )
    if "!.%%a!" neq "" set "a=!.%%a!"&call :loop&set ".%%a=!a!"
)
set /a num1=3-num_1+num_2,m=4-v
if defined flag set /a m=0
if %num1% leq 0 set /a num1=2
for /l %%a in (1,1,%num1%) do set /a num*=10
set /a s=%_1%%.1%*num/%_2%%.2%,j=%_1%%.1%*%_2%%.2%
if %j% lss 0 set "j=%j:-=%"&set "jk=-"
if %s% lss 0 set "s=%s:-=%"&set "sk=-"
if %m% neq 0 if "!j:~%m%!" equ "" set "j=0000%j%"&set "j=!j:~-%m%!"
if %s% lss %num% set "s=%num:~1%%s%"&set "s=!s:~-%num1%!"
if %m% neq 0 set "j=!j:~,-%m%!.!j:~-%m%,2!"
set "s=!s:~,-%num1%!.!s:~-%num1%,2!
for %%a in (s j) do (
    set "a=!%%a!"
    if "!a:.=!" equ "!a!" (
       set "%%a=!%%a!.00"
       ) else (
       if "!a:~-2,1!" equ "." set "%%a=!%%a!0"
    )
    if "!a:~,1!" equ "." set "%%a=0!%%a!"
)
echo 其积为:%jk%%j%&echo 其商为:%sk%%s%
pause>nul&goto :eof
:lp
set /a num_%n%+=1&set "a=%a:~1%"
if defined a goto lp
goto :eof
:loop
if "%a:~-1%" equ "0" set "a=%a:~,-1%"&set /a v+=1&goto loop

代码相当复杂,估计大家肯定会看得云里雾里,所以思来想去还
是补充代码编写思路如下,以便理解,同时期待高人出手,给出完美代码:

一、总体计算思路
大家知道本题最关键是在对小数点前后两部分数值的处理上,在楼上大家也有
过相关讨论。本人认为在加减法的处理上,应该是要将前后数值分开分别进行计
算然后再做处理(如后面小数位和满百位的处理),最后再在中间补上小数点。
而对乘法,则应是去掉小数点后前后位一起运算,最后从后向前移位补上小数点
。至于除法则是最复杂的,如结果要保留两位小数,你必须要保证除数的数位比
被除数多三位(两数均先去掉小数点),当这一条件没有得到满足时,就要给除
数后面补上足够的0,最后在结果中从后向前移位补上小数点。

二、对数值的处理
大家可以看到本人在代码中使用了海量的if语句来做判断,主要是为了处理各
种情况下的数值,大致将情况归纳如下面的12点:
1 处理原始数值无小数位的情况--从后面补上.00
2 处理原始数值小数位不满两位的情况--给小数位补上00并提取前面的两位
3 处理加减计算时小数位大于100的情况--小数位减去100,整数位加1
4 处理加减计算整数位为负小数位小于-100的情况--小数位加上100,整数位
减1
5 处理加减计算整数位为0小数位小于0的情况--整数位变为-0,小数位去掉负

6 处理加减计算整数位为正小数位小于0的情况--小数位加上100,整数位减1
7 处理加减计算小数位小于10的情况--在小数位前面加上0
8 处理乘除计算时两数小数位均为00的情况--将小数位置空
9 处理乘除计算时整数位为0的情况--对小数位进行取余运算
10 处理乘除计算时结果数位不够小数位的情况--在结果值前面补上足够的0并
从后向前提取小数位(如结果为负数还要先取掉负号最后再补上)
11 处理乘除计算时结果无小数位的情况--在结果后补上.00
12 处理乘除计算时结果小数位不足两位的情况--在结果后补上0

三、感言

在这次编写代码的过程中,本人深深感受到批处理在处理数值上的不足和缺陷
,这也是本人在出题时始料不及的。没想到其中要考虑的问题是方方面面错综复
杂,本人也曾几次在困难面前想要退缩,但为了给大家一个较满意的答案,还是
硬着头皮写了下来。看来批处理只适合做它适合做的事,想人为强加给它其他的
功能的确是费力不计好。

更多相关

批处理函数:大数字加减乘除、时期时间计算、数字排序、进制转换等

合理使用位运算可以简化代码、提高效率

位运算相关概念及批处理演示

https://www.jb51.net/article/222968.htm

https://www.jb51.net/article/222971.htm

对于超大数、浮点数的计算,BAT调用VBS或PowerShell是相对简单的解决方法。

截取日期、时间之后进行 set /a 计算时08和09会被看做非法八进制数字,参考:

https://www.jb51.net/article/222980.htm

https://www.jb51.net/article/222991.htm

五、使用 set 命令进行字符串截取

原始字符串 字符串截取 set sub=%str:~x,y% 结果

截取第一个到第三个字符

set str=12345
set sub=%str:~0,3%

截取第二个到最后一个字符

set str=12345
set sub=%str:~1%

截取倒数第四个到倒数第二个字符

set str=12345
set sub=%str:~-4,3%
set sub=%str:~-4,-1%

截取最后两个字符

set str=12345
set sub=%str:~-2%

说明

当x为正数时,表示从左到右截取;当x为负数时,表示从右到左截取。
当y为正数时,表示要截取后字符串的长度;当y为负数时,表示要抛弃的最后几个字符长度。
当y及其之前的逗号不存在时,表示截取的是第x+1个字符及其之后的所有字符。

六、使用 set 命令进行字符串替换

set StrNew=%StrOld:SubOld=SubNew%

把字符串 bbs 替换成 www

set StrOld=http://bbs.bathome.net
set StrNew=%StrOld:bbs=www% 

把字符串 bbs 删掉

set StrOld=http://bbs.bathome.net
set StrNew=%StrOld:bbs=% 

把第一字符 t 及其左侧所有字符全部删掉(统配符 * 的使用)

set StrOld=http://bbs.bathome.net
set StrNew=%StrOld:*t=%

待替换的子字符串不区分大小写(可以利用这个特性实现字母大小写转换)

@echo off
setlocal enabledelayedexpansion
REM 全部转换成大写字母
set str=http://bbs.BATHOME.net
set up=A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
for %%i in (%up%) do (
set str=!str:%%i=%%i! )
echo %str%
pause

全部转换成小写字母

@echo off
setlocal enabledelayedexpansion
REM 全部转换成小写字母
set str=http://bbs.BATHOME.net
set low=a b c d e f g h i j k l m n o p q r s t u v w x y z
for %%i in (%low%) do (
set str=!str:%%i=%%i! )
echo %str%
pause

七、set命令知识点(1)把命令结果赋值给变量

UNIX/Linux Shell 支持命令替换 Windows BAT 借助重定向或者for语句来实现

PacketLoss=`ping -c 4 127.0.0.1 | grep '%'`
echo $PacketLoss

bat

@echo off
REM 利用重定向把命令结果(单行字符串)赋值给变量
ping 127.0.0.1 | findstr "%%" > "%temp%\ping.txt"
set /p PacketLoss=<"%temp%\ping.txt"
echo %PacketLoss%
pause

shell

PacketLoss=$(ping -c 4 127.0.0.1 | grep '%')
echo $PacketLoss

bat

@echo off
REM 利用for语句把命令结果(单行字符串)赋值给变量
for /f "delims=" %%i in ('ping 127.0.0.1 ^| findstr "%%"') do (
set "PacketLoss=%%i"
)
echo %PacketLoss%
pause

八、set命令知识点(2)显示以某字符开头的变量

直接执行 set 命令可以显示系统环境变量
命令 set xxx 可以显示所有以 xxx 开头的变量
显示结果按照变量名进行排序

C:\>set xxx1=A
C:\>set xxx3=C
C:\>set xxx2=B
C:\>set xxx
xxx1=A
xxx2=B
xxx3=C

利用“排序”特性的完整代码演示

@echo off
for %%i in (a.txt c.txt b.txt e.txt) do (
set #%%i=%%i
)
for /f "tokens=2 delims==" %%i in ('set #') do (
echo %%i
)
pause

在解决实际问题中的应用

https://www.jb51.net/article/223002.htm

https://www.jb51.net/article/223004.htm

https://www.jb51.net/article/223007.htm

到此这篇关于批处理BAT脚本中set命令的使用详解(批处理之家Batcher)的文章就介绍到这了,更多相关set命令内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 批处理模式下运行 top 命令的方法

    top 命令 是每个人都在使用的用于 监控 Linux 系统性能 的最好的命令.你可能已经知道 top 命令的绝大部分操作,除了很少的几个操作,如果我没错的话,批处理模式就是其中之一. 大部分的脚本编写者和开发人员都知道这个,因为这个操作主要就是用来编写脚本. 如果你不了解这个,不用担心,我们将在这里介绍它. 什么是 top 命令的批处理模式 批处理模式允许你将 top 命令的输出发送至其他程序或者文件中. 在这个模式中,top 命令将不会接收输入并且持续运行,直到迭代次数达到你用 -n 选项指

  • 批处理之新窗口执行命令的脚本

    用bat脚本打开新窗口输出hello world: start "" cmd /k "echo hello world" ""表示新窗口没标题或者标题为空 /k表示执行完命令不关闭新窗口,/c表示执行完关闭窗口 1.用bat脚本打开一个新窗口,标题为tom,输出hello,两秒后输出world timeout /t 2倒计时两秒,也有人喜欢用ping,(ping 127.1 –n 2 >nul) 输出多个命令之间需要用&&符

  • 批处理copy命令的具体使用

    目录 示例 单个文件的复制 批量复制文件 合并文件 没有后缀的文件怎么复制? 本文的命令说明来自与DOS命令帮助说明,如果与DOS命令帮助说明不同,请以DOS命令帮助说明为准. 语法 copy[源盘符:][路径]<源文件名>[a|b][目标盘符:][路径]<目标文件>[a|b][/d][/v][/n][y|-y][/z][/?] copy<源文件名>+<源文件名2>[+……][<目标文件名>] copy con:[文件名全称] 参数 $ copy

  • 批处理命令批量复制文件并重命名的实现

    工作中如果需要把一个文件复制成N个内容一样且名称不一样的文件,可以使用批处理命令实现 步骤如下: 1.如现有文件名称为:test001.ini 文件 2.创建一个文件名称列表 FileList.txt,2种方式可以创建 1)是可以使用excel创建,然后复制到 FileList.txt 2)通过批处理命令实现 REM @echo off @echo off set name=FileList.txt set exc=.ini for /l %%i in (01,1,99) do ( echo %

  • 批处理命令call、start、goto的使用

    目录 1.call命令 1.1调用批处理 1.2调用目标标签 2.调用call 和不用call 的区别 3.goto 命令 4.start类似于创建一个线程 1.call命令 CALL从一个批处理程序调用另一个批处理程序,并且不终止父批处理程序.call命令主要有2种用法,一种是调用其他批处理程序(*.bat,*.exe,*.cmd,*.COM),目前常用的是*.exe文件和*.bat文件:另一种是CALL :label arguments C:\Users\Administrator>help

  • 批处理BAT脚本中set命令的使用详解(批处理之家Batcher)

    目录 一.使用 set 命令进行赋值 1.等号两边不要有空格 2.变量值包含特殊字符需用双引号 3.避免使用系统环境变量同名的自定义变量 4.语法可行但不推荐使用 二.使用 set /p 命令读取输入 三.使用 set /a 命令进行数学运算(1) 四.使用 set /a 命令进行数学运算(2) 五.使用 set 命令进行字符串截取 六.使用 set 命令进行字符串替换 七.set命令知识点(1)把命令结果赋值给变量 八.set命令知识点(2)显示以某字符开头的变量 一.使用 set 命令进行赋

  • 关于bat脚本中的命令状态码相关的%errorlevel%变量问题

    bat脚本中常用%errorlevel%表达上一条命令的返回值,即命令执行状态码.也称命令退出码 一般上一条命令的执行结果返回的值只有两种,0和非0 (如常见的1,2,4,5,9009等等),0一般会被视为成功,非0为失败或者异常 对于9009,在cmd中经常会发生输入的命令错误,或者不存在的命令,这时就会返回9009这种状态码, 1.对于%errorlevel%变量,一般都是与if结合使用较多,如下: dir qq5201351.txt if %errorlevel% ==0 (del /q/

  • Java中jstat命令的使用详解

    目录 jstat命令简介 jstat命令参数 输出选项 -class选项 -compiler选项 -gc选项 -gccapacity选项 -gcutil选项 -gccause选项 -gcnew选项 -gcnewcapacity选项 -gcold选项 -gcoldcapacity选项 -gcmetacapacity选项 -printcompilation选项 附实例使用:统计gc信息 总结 jstat命令简介 jstat(Java Virtual Machine Statistics Monito

  • Git中bundle命令的使用详解

    目录 1. 打包 2. 验证 3. 查看分支 4. 导入bundle 4.1. 没有gitlab服务器 4.2. 有gitlab服务器 4.2.1 从bundle中clone 4.2.2 从bundle中fetch 1. 打包 用git bundle create命令来打包 # dev指具体的分支名称,repo指项目代码仓库的名称 # 产生的repo.bundle 包含了所有重建该仓库 dev分支所需的数据 git bundle create repo.bundle HEAD dev 2. 验证

  • JS script脚本中async和defer区别详解

    一 引言 代码如下 <script src="https://www.google.com/recaptcha/api.js" async defer></script> 可以看到在script标签中,存在async与defer两个属性,首先这两个属性并共存,说直白点,你一个都不加,或者加两个属性其一,脚本加载规则都会不同,这点我在之前确实没仔细了解过,导致我在实际开发中遇到了这样一个问题: 我在同一个页面需要引用2个script脚本,大致如下: <scr

  • 基于shell脚本中cd命令无效的解决方法

    在学习的时候,经常要切换到固定的文件夹,于是写了个shell脚本用cd命令切换却发现目录切换不了. 代码如下: #! /bin/bash # c.sh cd /mnt/hgfs/vmshare pwd 解释:执行的时候是./c.sh来执行的,这样执行的话终端会产生一个子shell(类似于C语言调用函数),子shell去执行我的脚本,在子shell中已经切换了目录了,但是子shell一旦执行完,马上退出,子shell中的变量和操作全部都收回.回到终端根本就看不到这个过程的变化. 验证解释: #!

  • Shell脚本中多命令逻辑执行顺序的方法详解

    Linux中可以使用分号";".双and号"&&"和双竖线"||"来连接多个命令.单"&"符号也算命令连接符号,只不过它是将其前面的命令放入后台执行,所以可以变相地实现命令并行执行. 1.分号";" command1 ; command2 命令之间没有逻辑关系.分号连接的命令会按照顺序从前向后依次执行,但分号两端的命令之间没有任何逻辑关系,所有写出来的命令最终都会被执行,即使分号前面

  • shell 脚本中获取命令的输出的实现示例

    这个主要介绍的方法是获取命令的输出内容,而不是命令执行成功与否的返回值. 通常情况下,在shell脚本中需要获取命令的输出内容,然后根据输出内容判断下一步的执行操作. 比较常用的一种方式就是, 匹配命令输出的内容中是否存在某些关键字,选择执行的不同动作.比较常用的一种方式就是采用反向单引号的方式 --  保存结果的变量名=`需要执行的linux命令` 这种方式在使用时,有些细节的地方需要注意. 先用几个例子来说明一下. 比如在CentOS7环境中,使用rpm -qa命令查询某些rpm包是否安装,

  • 详解Linux中zip压缩和unzip解压缩命令及使用详解

    下面给大家介绍下Linux中zip压缩和unzip解压缩命令详解 1.把/home目录下面的mydata目录压缩为mydata.zip zip -r mydata.zip mydata #压缩mydata目录 2.把/home目录下面的mydata.zip解压到mydatabak目录里面 unzip mydata.zip -d mydatabak 3.把/home目录下面的abc文件夹和123.txt压缩成为abc123.zip zip -r abc123.zip abc 123.txt 4.把

  • python中的subprocess.Popen()使用详解

    从python2.4版本开始,可以用subprocess这个模块来产生子进程,并连接到子进程的标准输入/输出/错误中去,还可以得到子进程的返回值. subprocess意在替代其他几个老的模块或者函数,比如:os.system os.spawn* os.popen* popen2.* commands.* 一.subprocess.Popen subprocess模块定义了一个类: Popen class subprocess.Popen( args, bufsize=0, executable

随机推荐