【Windows批处理】for详解

基本用法

FOR %%i IN (command1) do command2

1、其中%%i,可以换成26个字母中的任意一个,这些字母会区分大小写;也可以是数字
2、command1 表示的字符串或变量可以是一个,也可以是多个;每一个字符串或变量,我们称之为一个元素,每个元素之间,用空格键、跳格键、逗号、分号或等号分隔
3、for语句依次提取command1中的每一个元素,把它的值赋予形式变量 i,带到do后的command2中参与命令的执行;如此循环,直到 command1 中的所有元素都已经被提取完毕,该 for 语句才宣告执行结束

栗子1:

@echo off
for %%i in (bbs,bathome,net) do echo %%i
pause

在这里插入图片描述
栗子2:显示盘符

@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

在这里插入图片描述
%%i:代表盘符,例如c:

栗子3:列出文件

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

在这里插入图片描述
这个 for 循环作用是 列出所有文件,所以文件夹没列出来
在这里插入图片描述

列出 .txt 的文件

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

在这里插入图片描述
如果增加的 cdf.txt 这样一个文件,需要排除这个,获取两个字以下文件

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

在这里插入图片描述

/f语句参数

有 a.txt,内容如下

aaaa
bbb
cc
d
@echo off
for /f %%i in (a.txt) do echo %%i

在这里插入图片描述
在这段代码中,虽然执行结果是把 a.txt 中的所有内容都显示出来了,貌似 for /f 语句是把整个a.txt一次性显示到屏幕上,实际上并非如此
for /f语句中,这里的元素是指文件中的每一行,也就是说,for /f 语句是以行为单位处理文本文件的
在这里插入图片描述
这段代码,主要是让你树立这样一种观念:逐行分析文本文件的内容,请使用 for /f 语句

delims=

a.txt内容

aaaaa,bbbb,ccc
dd,e
f
@echo off
for /f "delims=," %%i in (a.txt) do echo %%i

在这里插入图片描述
运行发现每行第一个逗号之后的所有内容都不见了(如果有不存在逗号的行,则保留原样),也就说,你成功地提取到了每行第一个逗号之前的所有内容
delims=,,它的含义是:以逗号作为被处理的字符串的分隔符号

你可以一次性指定多个分隔符号

aaaaa,bbbb.ccc
dd.e
f

在这里插入图片描述

tokens

使用 delims 的时候,for /f 默认只能提取到第一节的内容,如果要提取的内容不在第一节上,那怎么办?可以使用 tokens
tokens= 后面一般跟的是数字,可以跟一个或多个,每个数字之间用逗号分隔,如 tokens=3,5,8,它们的含义分别是:提取第2节字符串、提取第3、第5和第8节字符串。注意,这里所说的"节",是由 delims= 这一开关划分的

例如有 a.txt

aa,bb,cc,dd
ee,ff,gg,hh,ii,jj
kk
@echo off
for /f "delims=, tokens=3" %%i in (a.txt) do echo %%i

在这里插入图片描述
如果我想获取1、3节,可以写成这样吗

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

运行发现,只显示了第 1 节的内容
在这里插入图片描述
原来,echo 后面的 %%i 只接收到了 tokens=1,3 中第一个数值1所代表的那个字符串,而第二个数值3所代表的字符串因为没有变量来接收,所以就无法在执行结果中显示出来了

如果 tokens= 后面指定了多个数字,如果形式变量为%%i,那么,后边的形式变量分别用 %%i、%%j、%%k…来接收。形式变量遵循字母的排序。所以如果第一个形式变量是%%i,那么,第二个形式变量就是%%j;如果第一个形式变量用的是%%x,那么,第二个 形式变量就是%%y

知道的刚才代码的问题,修改如下

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

在这里插入图片描述
如果想要提取1,2,3,4 节内容你可以这样写

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

当然也有更简单的写法,前边写成 1-4,后边形式变量还是需要把变量写全

@echo off
for /f "delims=, tokens=1-4" %%i in (a.txt) do echo %%i %%j %%k %%l

运行结果是一样的
在这里插入图片描述
如果想读取从第 2 节开始的所有的内容可以这样写

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

在这里插入图片描述
第 2 节字符串被切分完之后,其余部分字符串不做任何切分,整体作为第二节字符串,整体被*所表示的一个变量接收

skip

有用的信息可能位于第N行之后的行内,为了提高文本处理的效率,for /f 允许你跳过这些无用的行,直接从第 N+1行开始处理,这个时候,就需要使用参数 skip=n,其中,n是一个正整数,表示要跳过的行数

例如有 a.txt

aa,bb,cc,dd
ee,ff,gg,hh,ii,jj
kk,ll,mm,nn
oo,pp,qq,rr,ss,tt,uu
vv,ww,xx,yy,zz
@echo off
for /f "skip=3" %%i in (a.txt) do echo %%i

在这里插入图片描述

eol

忽略以指定字符打头的行。例如有 a.txt

,aa,bb,cc,dd
,ee,ff,gg,hh,ii,jj
;kk,ll,mm,nn,
;oo,pp,qq,rr,ss,tt,uu
vv,ww,xx,yy,zz
for /f "eol=," %%i in (a.txt) do echo %%i

在这里插入图片描述
另外需要注意的是,for /f 语句是默认忽略以分号打头的行内容的,正如它默认以空格键或跳格键作为字符串的切分字符一样。(注:eol=;这种默认设置,在delims=;时变得无效。),所以在设计即将用 for 读取的配置文件的时候,可以在注释文字的行首加上分号,例如我们使用上边的代码再执行一遍现在的 a.txt

@echo off
for /f "skip=3" %%i in (a.txt) do echo %%i

因为跳过了前三行,所以按理说应该输出

;oo,pp,qq,rr,ss,tt,uu
vv,ww,xx,yy,zz

但是执行结果只输出了最后一行,所以证明 for /f 语句是默认忽略以分号打头的行内容的
在这里插入图片描述
如果要取消这个默认设置,可选择的办法是:
1、为eol=指定另外一个字符
2、使用 for /f “eol=” 语句,也就是说,强制指定字符为空,就像对付delims=一样

语式

1、for /f %%i in (文件名) do (……)
2、for /f %%i in ('命令语句') do (……)
3、for /f %%i in ("字符串") do (……)

1、如果读取文本文件中的内容,应使用的是第1条语句;例如:想显示 a.txt 中的内容,那么,就使用 for /f %%i in (test.txt) do echo %%i
2、当读取的是命令语句执行结果中的内容,第一个括号中的命令语句必须使用单引号包裹,应使用的是第2条语句;例如:显示当前目录下文件名中含有 test 的文本文件,应该使用 for /f %%i in ('dir /a-d /b *test*.txt') do echo %%i

/a-d 显示文件
/a d 显示目录
/b 显示文件名、扩展名

3、当要处理的是一个字符串,第一个括号中的内容必须用双引号括起来, 应该用第3条语句;例如:当你想把 www.baidu.com 这串字符中的点号换为短横线并显示出来,可以使用 @echo off for /f "delims=. tokens=1-3" %%i in ("www.baidu.com") do echo %%i-%%j-%%k

来看一个问题,如果存在一个文件 test 1.txt,那么怎么读取呢,你可能会直接采用第一条语句
for /f %%i in (test 1.txt) do echo %%i 运行后,提示你 系统找不到文件 test。这是我们需要使用 usebackq,同时文件名称也需要用 双引号 括起来

for /f "usebackq" %%i in ("test 1.txt") do echo %%i

usebackq 是一个增强型参数,当使用了这个参数之后,原来的for语句中第一个括号内的写法要做如下变动:
1、如果第一个括号里的对象是文件名的话,要用双引号"括起来,这样就可以包含一些特殊符号
2、如果第一个括号里的对象是一条命令语句的话,原来的单引号 ’ 要改为后引号`
3、如果第一个括号里的对象是字符串的话,原来的双引号"要改为单引号’

所以 for 有 6 中语式、

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 (……)

变量延迟

批处理程序在文件及文件夹管理中的应用实例 的最后,我们了解了变量延迟,这里再深入学习下

执行:

@echo off
set num=12
echo %num%
pause

运行结果:
在这里插入图片描述
运行:

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

运行结果如下,说明在复合语句内部是没有办法修改变量的值的
在这里插入图片描述
运行

@echo off
set num=0
for /f %%i in ('dir /a-d /b *.txt') do (
	set /a num+=1
	echo num 当前的值为 %num%
) 
echo 当前目录下共%num%个txt文件

运行结果如下,说明 for 循环语句的 do(…) 是一条语句,在一条语句中是不能再修改变量的
在这里插入图片描述
我们使用变量延迟,让复合语句内部的变量实时感知到变量值的变化
第一种方法: setlocal enabledelayedexpansion开启,变量用一对叹号!!括起来
运行:

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

在这里插入图片描述

@echo off
setlocal enabledelayedexpansion
set num=0
for /f %%i in ('dir /a-d /b *.txt') do (
	set /a num+=1
	echo num 当前的值为 !num!
) 
echo 当前目录下共%num%个txt文件

在这里插入图片描述
第二种方法: 使用call语句,在原来命令的前部加上call命令,并把变量引用的单层百分号对改为双层

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

在这里插入图片描述

@echo off
set num=0
for /f %%i in ('dir /a-d /b *.txt') do (
	set /a num+=1
	call echo num 当前的值为 %%num%%
) 
echo 当前目录下共%num%个txt文件

在这里插入图片描述
总结:
何时使用:
在复合语句内部,如果某个变量的值发生了改变,并且改变后的值需要在复合语句内部的其他地方被用到,那么,就需要使用变量延迟语句。而复合语句有:for语句、if……else语句、用连接符&、||和&&连接的语句、用管道符号|连接的语句,以及用括号括起来的、由多条语句组合而成的语句块。最常见的场合,则是for语句和if……else语句
使用方法:
第一种方法: setlocal enabledelayedexpansion开启,变量用一对叹号!!括起来,使用setlocal disabledelayedexpansion可以关闭变量延迟
第二种方法: 使用call语句,在原来命令的前部加上call命令,并把变量引用的单层百分号对改为双层

/r

for /r 的作用是“递归”,简单说叫"遍历文件夹",它会遍历指定目录和子目录下的所有文件和文件夹语法 for /r 目录 %%i in (元素集合) do 命令语句集合,其作用与嵌套进 for /f 复合语句的 “dir /ad /b /s 路径” 功能类似
现在 d:\test 中有 a、b两个文件夹。a 中有 a1.txt、a2.txt;b 中有 b1.txt、b2.txt

@echo off
for /r d:\test %%i in (.) do echo %%i
pause
for /f %%i in ('dir/ad/b/s d:\test') do echo %%i
pause
for /r d:\test %%i in (x y z) do echo %%i
pause

在这里插入图片描述
元素集合的含义是:列举 d:\test 及其所有的子目录,对所有的目录路径都分别添加x、y、z之后再显示出来

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

在这里插入图片描述
这段代码的含义是:列举 d:\test 及其所有子目录下的 txt 文本文件(以 .txt 结尾的文件夹不会被列出来)

关于 for /r 更多的解释查看末尾的更多

/d

为了处理文件夹 for /d %%i in (元素集合) do 命令语句集合
它仅能匹配当前目录下的第一级文件夹,或是指定位置上的文件夹,而不能匹配更深层次的子文件夹
例如想查看当前目录中有没有 test开头的文件夹

@echo off
for /d %%i in (test*) do echo %%i
pause

在这里插入图片描述

/l

先看例子

@echo off
for /l %%i in (1,2,10) do echo 麻花疼
pause

在这里插入图片描述
语法格式 for /l %%i in (x,y,z) do (……)
在这个语句中,x、y和z都只能取整数,正负皆可,x指代起始值,y指代步长,z为终止值。步长y的值不能为0

变量

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

我们可以看到每行都有一个大写字母"I",这"I"其实就是我们在FOR带入的变量,我们FOR语句代入的变量名是什么,这里就写什么

~I

首先建立一个 temp.txt,注意不成对的引号要加转义字符^,重定向符号前不要留空格

@echo off
echo ^"1111>temp.txt
echo "2222">>temp.txt
echo 3333^">>temp.txt
echo "4444"44>>temp.txt
echo ^"55"55"55>>temp.txt

然后使用 以下命令读取 temp.txt

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

在这里插入图片描述
使用以下命令去掉 引号

@echo off
for /f %%i in (temp.txt) do echo %%~i
pause

在这里插入图片描述
删除引号规则如下:
1、若字符串首尾同时存在引号,则删除首尾的引号;
2、若字符串尾不存在引号,则删除字符串首的引号;
3、如果字符串中间存在引号,或者只在尾部存在引号,则不删除

%~fI
将 %I 扩展到一个完全合格的路径名

@echo off
for /f %%i in ('dir /b') do echo %%i
pause

在这里插入图片描述
使用 ~fi

@echo off
for /f %%i in ('dir /b') do echo %%~fi
pause

在这里插入图片描述
%~dI
仅将 %I 扩展到一个驱动器号
在这里插入图片描述
%~pI
仅将 %I 扩展到一个路径
在这里插入图片描述
%~nI
仅将 %I 扩展到一个文件名
在这里插入图片描述
%~xI
仅将 %I 扩展到一个文件扩展名
在这里插入图片描述
%~sI
扩展的路径只含有短名
现在有文件
在这里插入图片描述
在这里插入图片描述
%~tI
将 %I 扩展到文件的日期/时间
在这里插入图片描述
%~zI
将 %I 扩展到文件的大小
在这里插入图片描述
%~$PATH:I
查找列在路径环境变量的目录,并将 %I 扩展到找到的第一个完全合格的名称。如果环境变量名未被定义,或者没有找到文件,此组合键会扩展到空字符串

@echo off
for /f %%i in ("EditPlus.exe") do echo %%~$PATH:i
pause

在这里插入图片描述
如果当前路径没有则
在这里插入图片描述
批处理-For详解
FOR命令中的变量

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章