批处理

if命令

常见用法:

if "字符串1" == “字符串2 command语句

if 数值1 equ 数值2 command语句

if exist filename command语句

if not exist filename command语句

if errorlevel 数值 command语句

if exist d:\test.txt (echo D盘下有test.txt存在) else (echo D盘下不存在test.txt)

for命令

基本用法

for %I in (command1) do command2

在批处理文件中:for %%I in (command1) do command2

  1. for、in和do是for语句的关键字,它们三个缺一不可;
  2. %%I是for语句中对形式变量的引用,就算它在do后的语句中没有参与语句的执行,也是必须出现的;
  3. in之后,do之前的括号不能省略;
  4. command1表示字符串或变量,command2表示字符串、变量或命令语句;

检测当前硬盘都有哪些分区

@echo off
set str=c d e f g h i j k l m n o p q r s t u v w x y z
echo 当前硬盘的分区有:
for %%i in (%str%) do if exist %%i: (echo %%i:)
pause

列出当前目录下所有的文本文件

@echo off
for %%i in (*.txt) do echo "%%i"
pause

/f 文件操作

读取文本文件的内容,使用 for /f 语句

  1. for /f %%i in (文件名) do (……)
  2. for /f %%i in ('命令语句') do (……)
  3. for /f %%i in ("字符串") do (……)
  4. for /f "usebackq" %%i in ("文件名") do (……)
  5. for /f "usebackq" %%i in (`命令语句`) do (……)
  6. for /f "usebackq" %%i in ('字符串') do (……)

无论for语句做何种变化,它的执行过程仍然遵循基本的for流程:依次处理每个元素,直到所有的元素都被处理为止。只不过在for /f语句中,这里的元素是指文件中的每一行,也就是说,for /f 语句是以行为单位处理文本文件的。

@echo off
for /f %%i in (test.txt) do echo %%i&pause
pause

delims

切分字符串的利器:delims=

@echo off
for /f "delims=," %%i in (test.txt) do echo %%i
pause

每行第一个逗号之后的所有内容都不见了。

如果没有指定"delims=符号列表"这个开关,那么,for /f 语句默认以空格键或跳格键

作为分隔符号。

@echo off
for /f "delims=.," %%i in (test.txt) do echo %%i
pause

第一个点号或第一个逗号之前的内容都被提取出来了

for /f 语句默认只提取第一节的符串

tokens

定点提取:tokens=

tokens= 后面一般跟的是数字,如 tokens=2,也可以跟多个,但是每个数字之间用逗号分隔,如 tokens=3,5,8,它们的含义分别是:提取第2节字符串、提取第3、第5和第8节字符串。注意,这里所说的“节”,是由 delims= 这一开关划分的,它的内容并不是一成不变的。

@echo off
for /f "delims=, tokens=3" %%i in (test.txt) do echo %%i
pause

如果 tokens= 后面指定了多个数字,如果形式变量为%%i,那么,第一个数字指代的内容用第一个形式变量%%i来接收,第二个数字指代的内容用第二个形式变量%%j来接收。

@echo off
for /f "delims=, tokens=2,5" %%i in (test.txt) do echo %%i,%%j
pause

for /f "delims=, tokens=1,2,3,4,5" %i in (test.txt) do echo %i %j %k %m %l

for /f "delims=, tokens=1,*" %%i in (test.txt) do echo %%i %%j

for /f "delims=, tokens=1,3-4,*" %%i in (test.txt) do echo %%i %%j %%k %%l

如果要提取的内容是连续的多“节”的话,那么,连续的数字可以只写最小值和最大值,中间用短横连接起来即可,比如 tokens=1,2,3,4,5 可以简写为 tokens=1-5

tokens=后面所接的星号具备这样的功能:字符串从左往右被切分成紧跟在*之前的数值所表示的节数之后,字符串的其余部分保持不变,整体被*所表示的一个变量接收。

skip

用的信息并不是贯穿文本内容的始终,而是位于第N行之后的行内,为了提高文本处理的效率,或者不受多余信息的干扰,for /f 允许你跳过这些无用的行,直接从第N+1行开始处理,这个时候,就需要使用参数 skip=n,其中,n是一个正整数,表示要跳过的行数。

@echo off
for /f "skip=2" %%i in (test.txt) do echo %%i
pause

eol

eol= 的准确含义是:忽略以指定字符打头的行,只能指定一个字符

@echo off
for /f "eol=,;" %%i in (test.txt) do echo %%i
pause

for /f 语句是默认忽略以分号打头的行内容的,正如它默认以空格键或跳格键作为字符串的切分字符一样。在设计即将用for读取的配置文件的时候,可以在注释文字的行首加上分号。

/r 文件夹操作

读取文本文件的内容,使用 for /f 语句

for /r 目录 %%i in (元素集合) do 命令语句集合

  1. 列举“目录”及该目录路径下所有子目录,并把列举出来的目录路径和元素集合中的每一个元素拼接成形如“目录路径\元素”格式的新字符串,然后,对每一条这样的新字符串执行“命令语句集合”中的每一条命令;
  2. 特别的是:当“元素集合”带以点号分隔的通配符?或*的时候,把“元素集合”视为文件(不视为文件夹),整条语句的作用是匹配“目录”所指文件夹及其所有子文件夹下匹配的文件;若不以点号分隔,则把“元素集合”视为文件夹(不视为文件);
  3. 当省略掉“目录”时,则针对当前目录;
  4. 当元素集合中仅仅是一个点号的时候,将只列举目录路径;
@echo off
for /r d: %%i in (.) do echo %%i
pause


@echo off
for /r d: %%i in (*.txt) do echo %%i
pause

/d 单层目录操作

当“元素集合”中包含有通配符?或*时,它会匹配文件夹,但是,相比 for /r 而言,这个时候的for /d,其作用就小得可怜了:它仅能匹配当前目录下的第一级文件夹,或是指定位置上的文件夹,而不能匹配更深层次的子文件夹。

for /d %%i in (元素集合) do 命令语句集合

for /d %i in (d:\*) do echo %i

for /d %i in (d:\CTF\*) do @echo %i

用处不多,只匹配当前路径下有哪些文件夹,不匹配子目录

/l 计数循环操作

loop计数循环,x、y和z都只能取整数,正负皆可,x指代起始值,y指代步长,z为终止值,具体含义为:从x开始计数,以y为步长,直至最接近z的那个整数值为止,这之间有多少个数,do后的语句就执行多少次。

for /l %%i in (x,y,z) do (……)

实际上,x,y和z的值可正可负,甚至为0,限制非常宽松:

  1. 步长y的值不能为0;
  2. 当步长y的值为正整数时,终止值z不能小于初始值x;
  3. 当步长y的值为负整数的时候,终止值z不能大于初始值x。

换而言之,必须保证in和do之间能取到一个有效的数组序列。

for /l %i in (1,2,10) do echo hello

延迟变量

批处理是“自上而下,逐条执行”

@echo off
set num=0
for /f %%i in ('dir /a-d /b *.exe') do (
    set /a num+=1
    echo num 当前的值是 %num%
)
echo 当前目录下共有 %num% 个exe文件
dir /a-d /b *.txt|findstr "test">nul&&(
    echo 存在含有 test 字符串的文本本件
)||echo 不存在含有 test 字符串的文本文件
if exist test.ini (
    echo 存在 test.ini 文件
) else echo 不存在 test.ini 文件
pause

 上面的代码共有14行,但是只有完整的语句只有7条,它们分别是:

  第1条:第1行的echo语句;

  第2条:第2行的set语句;

  第3条:第3、4、5、6行上的for复合语句;

  第4条:第7行的echo语句;

  第5条:第8、9、10行上用&&和||连接的复合语句;

  第6条:第11、12、13行上的if……else复合语句;

  第7条:第14行上的pause语句。

@echo off
set num=0&&echo %num%
pause

执行结果:ECHO 处于关闭状态

是因为预处理的机制,set num=0&&echo %num%是一条指令,%num%实际是引用之前的num赋值,但实际无赋值,所以会报错。

使用setlocal enabledelayedexpansion 语句延迟变量可以改写为:

@echo off
setlocal enabledelayedexpansion
set num=0&&echo !num!
pause


@echo off
set num=0
setlocal enabledelayedexpansion
for /f %%i in ('dir /a-d /b *.exe') do (
    set /a num+=1
    echo num 当前的值是 !num!
)
echo 当前目录下共有 %num% 个exe文件
dir /a-d /b *.txt|findstr "test">nul&&(
    echo 存在含有 test 字符串的文本本件
)||echo 不存在含有 test 字符串的文本文件
if exist test.ini (
    echo 存在 test.ini 文件
) else 不存在 test.ini 文件
pause

使用Call语句,改写为

@echo off
set num=0&&call echo %%num%%
pause


@echo off
set num=0
for /f %%i in ('dir /a-d /b *.exe') do (
    set /a num+=1
    call echo num 当前的值是 %%num%%
)
echo 当前目录下共有 %num% 个exe文件
dir /a-d /b *.txt|findstr "test">nul&&(
    echo 存在含有 test 字符串的文本本件
)||echo 不存在含有 test 字符串的文本文件
if exist test.ini (
    echo 存在 test.ini 文件
) else 不存在 test.ini 文件
pause

  1、为什么要使用变量延迟?因为要让复合语句内部的变量实时感知到变量值的变化。
  2、在哪些场合需要使用变量延迟语句?在复合语句内部,如果某个变量的值发生了改变,并且改变后的值需要在复合语句内部的其他地方被用到,那么,就需要使用变量延迟语句。而复合语句有:for语句、if……else语句、用连接符&、||和&&连接的语句、用管道符号|连接的语句,以及用括号括起来的、由多条语句组合而成的语句块。最常见的场合,则是for语句和if……else语句。
  3、怎样使用变量延迟?
  方法有两种:
  ① 使用 setlocal enabledelayedexpansion 语句:在获取变化的变量值语句之前使用setlocal enabledelayedexpansion,并把原本使用百分号对闭合的变量引用改为使用感叹号对来闭合;
  ② 使用 call 语句:在原来命令的前部加上 call 命令,并把变量引用的单层百分号对改为双层。

posted @ 2023-04-18 17:20  RichardMrZ  阅读(44)  评论(0编辑  收藏  举报