Windows批处理教程

Windows批处理教程前言Windows操作系统除了用户接口【也叫外壳,shell】,还有编程接口。用户接口又分为图形用户接口,即资源浏览器(explorer.exe),命令用户接口,即命令解释器(command.com或cmd.exe)。批处理程序是被操作系统命令解释器解释执行的文本程序。从这种角度看,命令既是用户接口,也是编程接口。因为这方面的资料很零散,很不全面,很不简洁,所以我收集整理了比较全面的资料供大家参…

Windows批处理教程"

前言

Windows操作系统除了用户接口【也叫外壳,shell】,还有编程接口。用户接口又分为图形用户接口,即资源浏览器(explorer.exe),命令用户接口,即命令解释器(command.com或cmd.exe)。批处理脚本是被操作系统命令解释器解释执行的文本文件。从这种角度看,命令既是用户接口,也是编程接口。因为这方面的资料很零散,很不全面,很不简洁,所以我收集整理了比较全面的资料供大家参考。

现在存在两种批处理命令。.bat是MS-DOS批处理文件,运行于MS-DOS和Windows 9x和Windows ME。.cmd是Windows NT命令脚本,只能被cmd.exe执行。cmd.exe是command.com的再实现和扩展。现在你可以随意取.bat或.cmd扩展名,这两种文件的唯一区别是对errorlevel变量的更新。.cmd文件在命令扩展打开的条件下,命令执行无论成功失败都会更新errorlevel变量,而.bat文件仅在命令失败的条件下更新errorlevel变量。

cmd.exe提供的命令的表现能力很弱,而且效率低下,远远落后于Unix操作系统的外壳提供的命令。这是因为微软早期不重视批处理脚本的缘故。之后微软在Windows 98上推出了Windows Script Host,运行ActiveX脚本引擎,VBScript、JScript、Perl、Python都可以作为它的编程语言,虽然它的表现力很强大【取决于特定的脚本语言】,但是它写的脚本可能依赖非本地解释器,而且还存在安全性差的缺点,导致了很多脚本病毒,而且它不是一个通常意义的外壳,比如缺乏cd命令,不能在命令行上交互。现在微软在Windows 7上推出PowerShell,通过脚本签名和执行策略增强了安全性。这是一个非常强悍的极其优秀的自动化脚本语言,因为面向对象、集成.net类库、在管道间传递对象而非文本等等优秀特性,我认为它已经较大地超越了Unix的外壳。那么为什么还要学习老的批处理呢?因为老的批处理环境是无处不在的,而PowerShell在Windows XP上却需要安装,还有旧的批处理代码需要维护。

Visual studio为了能自动化编译工程,提供了vcvarsall.bat脚本。Visual Studio Command Prompt就是预先调用了这个脚本的cmd.exe,例如在我的机器上,它的目标就是%comspec% /k ““C:\Program Files\Microsoft Visual Studio 10.0\VC\vcvarsall.bat”” x86。由此可见,在一段时间内批处理还是不会消亡的。等到PowerShell占统治地位的时候,传统批处理就该彻底退出历史舞台了。

微软的批处理命令参考网站:

A-Z List
我参考了一些书籍和很多网络资源,结合自己的理解,以简略的风格进行讲解。学习者应该勤于试验,掌握概念的意义和命令的用法。

命令语法表示法

本文和微软批处理命令参考网站对于命令语法采用同一表示法。熟悉这些表示法能帮助你了解怎么书写一个命令。

表示法 描述
不在角括号或花括号中的文字 表示你必须原样键入的项
<角括号中的文字> 你必须使用一个值来取代的标记
[方括号中的文字] 可选项,也就是可以出现,也可以不出现
{花括号中的文字} 必选项集合,选择其中一个选项
竖杠 | 多个互斥项的分割符,只能选择其中之一
省略号 … 可以重复的项

帮助

键入help命令,查看支持的所有内部命令。键入help 或者 /?查询某个内部命令的帮助。 /?或者通常会提供外部命令的用法和帮助。如果你自己写了一个控制台程序,也最好遵守这个规则。

启动、退出和中止

在运行对话框键入cmd.exe打开一个命令行实例。如果要退出,键入exit命令,或关闭命令行窗口。如果要中止正在执行的命令,键入Ctrl+C,并在要求确认时键入y。

命令

命令是批处理的执行单元。命令分为简单命令复合命令。复合命令是使用() & && ||把简单命令组合起来成为一个命令。简单命令又分两种,内部命令【或者叫固有命令】和外部命令。内部命令是命令解释器cmd.exe提供的命令,外部命令是控制台程序,可以用任何编程语言编写。当内部命令不够用时,就需要寻找或编写外部命令。

控制台程序就是带有控制台的程序,控制台是标准输入标准输出标准错误输出的结合体。

通常情况下,一行就是一个命令。如果希望把一个命令分成几行,那么必须使用续行符^,而且必须放在行末,之后连空格也不能有。例如:

echo hello ^
cls

输出hello cls

()复合命令可以占多行,但其包含的单个命令必须每个占一行。

在命令名字后加.可以代替空格作为分隔符,还有一样好处,例如

echo %<varname>%
echo.%<varname>%

有什么区别呢?
区别就是当<varname>没有定义时,前者等价于echo后者等价于echo.。显然后者符合一般的期望。

命令中的文件路径分隔符必须使用\,不能是/,因为后者是命令选项前缀。

示例 说明
echo hello, world! ·hello, world!·
echo 显示回显开关状态
echo. 输出空行
echo off 命令回显关闭,@可以放在命令前表示本命令回显关闭
echo on 命令回显打开

批处理脚本调试

通常批处理脚本第一行就是@echo off关闭命令回显。如果在调试的时候,应该打开回显,观察每个命令的输出,必要时添加适当的set varname或echo %varname%来观察变量的值。当然也可以写一个带编辑器和调试器和捕获控制台输入输出的批处理开发环境。该编辑器应该可以对代码进行分析并进行语法着色,最好还能有点智能提示。该调试器可以单步执行、可以设置断点、可以显示想要观察的变量的值或所有变量的值。希望有这方面的优秀的开源软件出现。我自己写了一个可以设置断点,可以观察变量值的批处理调试程序,但是不可以单步执行。

注释

使用rem命令添加注释,也可以使用::添加注释,Notepad++可以识别这两种注释。有人也用无效的变量引用来添加行内注释,例如%==This is a comment==%

变量

变量分预定义变量自定义变量。也可分为系统变量本地变量。本地变量只存在于当前的cmd.exe进程。变量名不区分大小写。
预定义变量通常是系统环境变量用户环境变量。常用预定义变量包括ComSpec、Path、PathExt、windir、SystemRoot、SystemDrive、ProgramFiles、TEMP、TMP、PROCESSOR_ARCHITECTURE、NUMBER_OF_PROCESSORS、OS。其中PathExt指定可执行文件的扩展名,Path指定可执行文件和DLL的搜索路径。
还有一种预定义变量是命令解释器提供的,不能使用set命令查看和赋值的。例如%date%、%time%、%random%、%errorlevel%、%cmdextversion%、%cmdcmdline%等。PROMPT变量是个例外。
用户可以使用set命令添加、删除、显示和修改变量,自定义变量名字要避开预定义变量名。
任何变量都可以使用%<varname>%进行引用。

示例 说明
Set 显示所有变量
Set <varname> 显示以var开头的所有变量
Set <varname>= 删除var变量
Set <varname>=<value> 设置var变量
set /p <varname>=[<prompt>] 从控制台输入变量值
set /a <varname>=<expression> 对等号右侧进行算术运算,然后赋值给变量,支持的运算符可以参考微软的网站

变量求值

批处理命令的执行规则:在一个命令执行前,先把变量引用%var%置换为变量的当前值,然后执行替换后的命令。也就是说,在命令执行过程中,该变量引用已经不存在。例如:

set unknown=5
echo %unknown% & set unknown=0 & echo %unknown%

输出
5
5
而不是
5
0
如果命令回显开关打开,你可以看到执行的命令是:

echo 5   & set unknown=0   & echo 5

& && || 连接起来的命令算一个命令,()内的命令算一个命令,if和for命令算一个命令,因此都适用前面的规则。
如果希望在命令执行过程中保持变量引用,那么需要启用变量延迟求值
Setlocal enabledelayedexpansion
同时使用!<varname>!来引用变量。

变量作用域

如果希望在某个范围内增加变量、删除变量或者修改变量,一旦出了该范围,就完全无效,可以使用下面的命令对:

setlocal [enableextensions | disableextensions] [enabledelayedexpansion | disabledelayedexpansion]
endlocal

这个命令对保证了在执行setlocal命令之前和执行endlocal之后,所有变量完全是相同的,即已经定义的变量一样多,每个变量的值也是一样的。这个功能对于写包含多个批处理文件的工程是非常有用的,可以保证每个脚本执行的环境是比较干净的。

但是在用变量返回结果的函数中,是不可以用setlocal的,因为一旦你使用,那么你在该范围内所做的变量运算和赋值,一旦出了该范围,就完全撤销。例如本文末尾的strlen函数,是不可以使用setlocal的。后来在网上看到一种利用()复合命令的巧妙方法,使得既可以用变量返回值,同时又用setlocal屏蔽临时变量【例如strlen函数中的inputstr就是一个临时变量】。如果不想通过固定的变量返回计算结果,可以让用户传入返回变量名。

:strlen
 set /a strlen=0
 setlocal
 set inputstr=%1
 :countchar
 if not "%inputstr%"=="" (
  @set /a strlen+=1
  @set inputstr=%inputstr:~1%
  @goto :countchar
 )
 (
 endlocal
 set strlen=%strlen%
 )
 goto :eof

::在执行复合命令前,还没有调用endlocal,所以%strlen%会被替换为计算结果。执行endlocal后,strlen值为0,但是后面的set strlen=%strlen%又把strlen设置为正确的值。把变量求值的规则和变量作用域的规则结合起来,真是巧妙啊!这也是批处理的缺点,因为表现力差,很小的问题都需要太多的技巧。

setlocal是可以嵌套的,而且其行为是符合正常的期望的,我就不举例了。

如果只有setlocal调用,没有对应的endlocal调用,那么在批处理脚本或者函数调用返回时,存在相应的隐式endlocal调用。

转义字符

批处理有一些特殊字符,比如 |【管道】 &【连接】 <【输入重定向】 >【输出重定向】 ^ 【转义字符】,变量名或命令中如果含有这些字符,需要^进行转义。例如:
Set you^&I=David ^& Tom
如果不使用转义字符,可以使用双引号
Set "you&I=David & Tom"
和上面一句的效果是一样的。
注意命令中出现特殊字符也是要通过上述方法处理,例如:
Echo hello, David & Tom
会被解释为先执行Echo hello, David命令,然后执行Tom命令。
Echo hello, David ^& Tom
可以达到预期的结果。而
Echo "hello, David & Tom"
会连引号一起显示。

If命令

if [not] ERRORLEVEL <Number> <Command> [else <Expression>]
如果ERRORLEVEL大于等于<Number>,条件为真。ERRORLEVEL等于上次命令的退出码。对于C程序,退出码就是main函数的返回的整数值,或者其他函数使用exit(<Number>)结束进程时返回的值。对于批处理脚本,使用exit /b <Number>返回退出码,除此之外退出码为0。 按照批处理的惯例,返回值为0表示成功,非0表示失败,最好不要使用负数,因为便于编写批处理脚本,你编写的控制台程序或者批处理脚本也应该遵守这个惯例。
if [not] <String1>==<String2> <Command> [else <Expression>]
if [not] exist <FileName> <Command> [else <Expression>]
当文件存在是,条件为真。
Not对条件取反。
如果条件为真,执行条件后的命令,否则如果存在else部分,执行else之后的命令。
如果使用setlocal enableextensions打开了命令扩展,那么可以使用下面的命令。
if [/i] <String1> <CompareOp> <String2> <Command> [else <Expression>]
<String1><String2>都可转化为数字时,执行数字比较。否则执行字符串比较。
If /i <String1> == <String2> <Command> [else <Expression>]
这种写法是允许的。
if cmdextversion <Number> <Command> [else <Expression>]
当命令解释器的版本大于等于<Number>时条件为真。
if defined <Variable> <Command> [else <Expression>]
<Variable>定义时条件为真。
批处理的if命令的条件不支持与或逻辑运算。

  • 与运算模拟:
    If <condition1> if <condition2> <command>
    <condition1><condition2>都为真时执行<command>
    如果要实现else部分,可以借助一个中间变量实现,例如:
set cond1_and_cond2=
If <condition1> if <condition2> set cond1_and_cond2=true
If "%cond1_and_cond2%"=="true" <command> else <expression>
  • 或运算模拟:
set cond1_or_cond2=true
If not <condition1> if not <condition2> set cond1_and_cond2=false
If “%cond1_or_cond2%”==”true” <command> else <expression>

For命令

for {%%|%}<Variable> in (<Set>) do <Command> [<CommandLineOptions>]
如果在命令行中直接使用for命令,循环变量名以一个%来开头,例如%i。
如果在批处理文件中,循环变量名必须用两个%%开头,这是为了让命令解释程序能够区分批处理脚本或函数的参数【%0,%1,…,%9】和for命令变量【用两个%%开头】。
变量名必须是单个字符,大小写敏感,而且必须使用字母。【但事实上使用数字如%%0和标点符号如%%*也是可以的,但不推荐使用。】
<Set>可以是一组或多组文件,可以使用*通配符,例如:

(*.doc)
(*.doc *.txt *.me)
(jan*.doc jan*.rpt feb*.doc feb*.rpt)
(ar??1991.* ap??1991.*)

例如:for %%i in (*.doc *.txt) do echo %%i
显示当前目录下所有的.doc和.txt文件名。
命令的执行过程:

  1. 获得<set>集合。
  2. 对于<set>集合的每一个元素,替换循环变量如%%i,然后执行do后的命令。

for /d %%i in (*) do @echo %%i
显示当前目录下所有的目录名。
for /r /d %%i in (*) do @echo %%i
递归显示当前目录的所有子目录。
for /L %%i in (1,2,9) do @echo %%i
显示1 3 5 7 9
For /f命令应该重点讲解。
for /f ["<ParsingKeywords>"] {%%|%}<Variable> in (<Set>) do <Command> [<CommandLineOptions>]
这个命令用于解析文件内容。
<Set>是文件集合,但不可使用通配符。命令将对其中的每个文件逐行进行解析。例如下面的命令将打印1.bat和2.bat的每一行:
for /f "tokens=*" %%i in (1.bat 2.bat) do @echo %%i

for /f ["ParsingKeywords"] {%%|%}<Variable> in ("<LiteralString>") do <Command> [<CommandLineOptions>]
这个命令用于解析字符串。例如:
for /f "tokens=1* delims==" %%i in ("meal=20") do @echo you spend %%j yuan on %%i.
输出:
you spend 20 yuan on meal.
for /f ["<ParsingKeywords>"] {%%|%}<Variable> in ('<Command>') do <Command> [<CommandLineOptions>]
这个命令用于解析命令的输出。例如:
for /f "tokens=1,2,3 delims=- " %%i in ('date /t') do @echo year=%%i,month=%%j,date=%%k
输出:
year=2011,month=11,date=19
下面讲解for /f命令中的<ParsingKeywords>
eol=<c>
eol表示忽略第一个可视字符是字符的行。例如:
for /f "tokens=* eol=#" %%i in (test.pl) do @echo %%i
这个命令不会显示test.pl中的以#开头注释。
skip=<N>
忽略文件开头的前<N>行。
delims=<xxx>
指定行内分隔符集合,可以是多个字符,如果分隔符包含空格,必须把delims放在<ParsingKeywords>的最后,而且空格在所有分割符的最后,像我上面显示年月日的例子那样。缺省是空格和tab。
tokens=<X,Y,M-N>
X,Y,M,N都是正整数。指定要从每行提取的token的序号。对于每个序号都会按照字母顺序分配一个变量。M-N 指定一个范围, 表示从M到N个tokens. 如果最后一个是*, 会分配一个额外的变量,表示该行最后一个token之后余下的文字。例如假如循环变量是%%i,tokens=1-4表示提取前4个token,分别用%%i,%%j,%%k,%%l表示;tokens=2,4*表示提取第2个token,用变量%%i表示,提取第4个token,用%%j表示,第4个token之后剩下的文字用%%k表示。
For命令中文件路径的变量替换也很重要,大家自己看微软的文档吧。

多行If和For命令注意事项

多行if命令不能这么书写:

if %varname%==value
(
	echo varname==value
)
else
(
	echo varname!=value
)

这样写,命令解释器会把它看成4个命令,if、()、else、()。
应该这么写:

if %varname%==value (
	echo varname==value
) else (
	echo varname!=value
)

这里利用了()的跨行功能。多行For命令的写法也是一样。

调用其他批处理脚本

应该使用call来调用其他批处理脚本。如果不使用call,调用结束后批处理不会继续执行下去。不知道微软为什么要这样做?是一个bug还是故意这么设计?我觉得完全应该是否使用Call都应该返回。

但是如果你在()中调用其他批处理脚本,无论用不用Call都会返回。

%0表示批处理文件名【不含路径,不含扩展名】,从%1到%9是批处理调用参数%*表示从%1开始的全部参数。

shift命令可以用来从一个参数开始移动参数,可以处理参数超过9个的情况。

%~nx0表示批处理文件名【不含路径,但包含扩展名】,%~f0表示全路径名,%~dp0表示文件路径。这些参数替换也适用于其他批处理参数,从%1到%9,只要它们是存在的文件名。关于参数替换,可以参考call命令。

函数

批处理函数使用标签来标识入口,使用exit /b <n>goto :eof退出函数

如果使用call调用函数,%0表示函数名,%1、%2等表示函数调用参数。%*表示从%1开始的全部参数。

如果使用goto调用,那么%0,%1,…,%9的意义和调用批处理的参数一样。

shift命令可以用来从一个参数开始移动参数,可以处理参数超过9个的情况。

批处理函数使用call来调用,标签前面必须有:,以和批处理脚本区分。

示例:

@echo off
call :function1 h g
call :function2 x y
exit /b 0
:function1
echo %1
echo %2
echo %0
exit /b 0
:function2
echo %1
echo %2
echo %0
goto :eof

在命令行输入:
test2 b1 b2
输出如下:

h
g
:function1
x
y
:function2

如果使用goto来跳转到批处理函数,与call调用的区别有两点:

  1. goto跳转不会返回到调用点的下一个语句。
  2. %0、%1、%2会被解释成该批处理文件调用的参数。

示例:
如果把第一函数调用的call改成goto,在命令行输入:
test2 b1 b2
输出如下:

b1
b2
test2

建议使用call调用批处理函数,使用exit /b退出批处理函数并设置退出代码供调用者检查。
批处理只能调用本文件定义的函数,不能调用外部函数。

管道和重定向

管道符号是 |,<command1> | <command2>表示把<command1>的输出作为<command2>的输入。
例如:find "Jones" maillist.txt | sort
从maillist.txt寻找包含Jones的行,进行排序,然后输出。
输入重定向符号是 <,例如:
<command> < <somefile>表示<command>命令从<somefile>获得输入,而不是从控制台。
例如sort < name.txt表示对name.txt的行进行排序,然后显示在控制台上。

输出重定向符号是>,<command> > <somefile>,例如:
Echo hello, world> xxx.txt
Echo>xxx.txt hello, world
都是把hello, world写入xxx.txt文件。注意第二种形式echo和>之间没有空格,如果有,会输出一个空格在hello, world前面。

输出附加重定向符号是>>,<command> >> <somefile>,例如:
Echo hello, world>> xxx.txt
Echo>>xxx.txt hello, world

<command> [1]>nul
表示不输出一般信息。

<command> 2>&1
表示把错误输出到标准输出。

例如
del notexistfile 2>&1
del notexistfile 1>nul 2>&1

表示既不输出一般信息,也不输出错误,闷头干活。

命令连接符

&用来连接两个命令,按顺序执行,而不管前一个命令执行是否成功;
&&用来连接两个命令,当前一个命令执行成功时【%errorlevel%等于0】,执行后一个命令,否则不执行;
||用来连接两个命令,当前一个命令执行失败时【%errorlevel%不等于0】,执行后一个命令,否则不执行;

变量值(字符串)的截取和替换

%<varname>:~<start>[,<count>]%
上式表示从<varname>值的第<start>字符开始,截取<count>个字符。
如果从左边数起,<start>从0开始增一计数;
如果从右边数起,<start>从-1开始减一计数;
如果<count>省略,表示从<start>开始截取剩余字符串。

举例:

set text=abcdefg
echo %text:~0,4% & rem abcd
echo %text:~3,1% & rem d
echo %text:~-3% & rem efg
echo %text:~-5,2% & rem cd

%<varname>:<old>=<new>%
上式表示把<varname>中的<old>全部替换为<new><new>可以为空。<old>可以用通配符*开头。
举例:

set text=I love you.
echo %text:love=hate% & rem I hate you.
echo %text: =% & rem Iloveyou.
set text=desert is my destination
echo %text:*t=% & rem  is my destination

变量的嵌套和替换–Call命令的另类用法

使用Call与其他命令的组合允许变量嵌套,这是一个很有用的特性。
这个主题有点复杂,先搞一个例子激起大家的兴趣:

@echo off
call :GetMonthNumber May
set MonthNumber
call :GetMonthNumber Nov
set MonthNumber
goto :eof

rem---- Translate name of month into two digit number ----
:GetMonthNumber
set map=Jan-01;Feb-02;Mar-03;Apr-04;May-05;Jun-06;Jul-07;Aug-08;Sep-09;Oct-10;Nov-11;Dec-12
:: replace *%1- with empty string. Call is necessary.
call set MonthNumber=%%map:*%1-=%%
:: replace all ; with &rem.
set MonthNumber=%MonthNumber:;=&rem.%
goto :eof

输出:

MonthNumber=05
MonthNumber=11

怎么样?有兴趣就继续看下去。

先举个简单的例子:

@echo off
set a=b
echo %a% & rem 1
echo %%a%% & rem 2
echo %%%a%%% & rem 3
echo %%%%a%%%% & rem 4
echo %%%%%a%%%%% & rem 5

输出是:
b
%a%
%b%
%%a%%
%%b%%

解释:

批处理的替换规则如下:

替换过程总是由内而外进行的。

  1. 当最内层变量引用之前的百分号数目是偶数时,不执行变量替换。
    是奇数时,执行变量替换。
    替换后相邻百分号的数目在两种情况下都是偶数,替换为一半数量的百分号。
  2. 如果存在n个call调用,再重复n次上述过程,总共n+1次上述过程。

运用上述规则做个习题:

@echo off
set greet=hello, chendeping
set part1=gr
set part2=et
set part2ref=part2
echo %%%%%part1%e%%%part2ref%%%%%%%
call echo %%%%%part1%e%%%part2ref%%%%%%%
call call echo %%%%%part1%e%%%part2ref%%%%%%%

输出:

%%gre%part2%%%
%greet%
hello, chendeping

看懂上面的例子,看完这个教程,批处理知识掌握的就差不多了,剩下的任务就是在实践中掌握各种命令了。

常用内部命令

Attrib
Call
Cd (chdir)
Cls
Cmd
Color
Comp
Copy
Date
Del
Dir
Echo
Endlocal
Exit
Fc
Find
Findstr
For
Goto
If
Ipconfig
Label
Md (mkdir)
Mode
More
Move
Net user
Pause
Popd
Pushd
Rd (rmdir)
Reg
Regsvr32
Rem
Ren
Replace
Robocopy
Set
Setlocal
Shift
Shutdown
Sort
Start
Subst
Taskkill
Tasklist
Time
Timeout 【cmd暂停执行一段时间,就是大家梦寐以求的sleep功能,很可惜XP不支持】
Title
Type
Ver
Verify
Xcopy

以下脚本可以把除了SC以外的内部命令帮助保存到help.txt文件中。其中strlen函数可以求变量的长度,返回值保存在%strlen%中。

注意如果<varname>在复合命令中发生改变,一定要使用变量延迟求值,保持变量引用。

@echo off
setlocal ENABLEDELAYEDEXPANSION
if exist help.txt del help.txt
for /f "skip=1" %%i in ('help') do (
 set command=%%i
 if not "!command!"=="SC" (
  for /f "usebackq" %%j in (`help !command! ^| find /c "This command is not supported by the help utility."`) do (
   if %%j==0 (
    echo.>>help.txt
    call :strlen !command!
    set /a "left=(80-!strlen!)/2"
    set /a "right=80-!left!-!strlen!"
    set titlesep=
    for /l %%k in (1,1,!left!) do set titlesep=!titlesep!*
    set titlesep=!titlesep!!command!
    for /l %%k in (1,1,!right!) do set titlesep=!titlesep!*
    echo>>help.txt !titlesep!
    help>>help.txt !command!
   )
  )
 )
 if /i "!command!"=="XCOPY" exit /b 0
)
goto :eof

:strlen
 set /a strlen=0
 set inputstr=%1
 :countchar
 if not "%inputstr%"=="" (
  @set /a strlen+=1
  @set inputstr=%inputstr:~1%
  @goto :countchar
 )
 goto :eof

今天的文章Windows批处理教程分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/30880.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注