你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

请问批处理中的%%f是什么意思?

[复制链接]
beary 提问时间:2016-6-14 12:34 /
在批处理文件中看到了
%%f, 查了一下,表示%f,
可是查不到%f表示什么意思。。


还有一个就是有一句话是这样的
set progs=!progs!
请问这个如何理解呢

请问有熟悉的吗?

出现在如下的批处理中
setlocal enabledelayedexpansion
for %%f in (program\*.*) do @if not %%f==program\bt.c if not %%f==program\patch.c if not %%f==program\sim.cset progs=!progs! %%f
type program\bt.c%progs%


收藏 评论2 发布时间:2016-6-14 12:34

举报

2个回答
无薪税绵 回答时间:2018-3-5 11:05:34
看完,你就明白了:

FOR这条命令基本上都被用来处理文本,但还有其他一些好用的功能!
看看他的基本格式(这里我引用的是批处理中的格式,直接在命令行只需要一个%号)

FOR 参数 %%变量名 IN (相关文件或命令) DO 执行的命令
参数: FOR有4个参数 /d   /l   /r   /f   他们的作用我在下面用例子解释
%%变量名 :这个变量名可以是小写a-z或者大写A-Z,他们区分大小写,FOR会把每个读取到的值给他;
IN:命令的格式,照写就是了;
(相关文件或命令) :FOR要把什么东西读取然后赋值给变量,看下面的例子
do:命令的格式,照写就是了!
执行的命令:对每个变量的值要执行什么操作就写在这。

可以在CMD输入 for /? 看系统提供的帮助!
对照一下
FOR %%variable IN (set) DO command [command-parameters]
%%variable                      指定一个单一字母可替换的参数。
(set)                                 指定一个或一组文件。可以使用通配符。
command                          指定对每个文件执行的命令。
command-parameters        为特定命令指定参数或命令行开关。


现在开始讲每个参数的意思
/d      表示仅为目录 , 它只能显示当前目录下的目录名字,这个大家要注意!
如果 Set (也就是我上面写的 "相关文件或命令") 包含通配符(* 和 ?),
将对与 Set 相匹配的每个目录(而不是指定目录中的文件组)执行指定的 Command。
语法是:
FOR /d %%variable IN (set) DO command

他主要用于目录搜索,不会搜索文件,看下面的例子:
@echo off
for /d %%i in (*) do @echo %%i
pause
把他保存放在C盘根目录执行,就会把C盘目录下的全部目录名字打印出来,而文件名字一个也不显示!

再来一个,比如我们要把当前路径下文件夹的名字只有1-3个字母的打出来
@echo off
for /d %%i in (???) do @echo %%i
pause
这样的话,如果你当前目录下有目录名字只有1-3个字母的,就会显示出来,没有就不显示了。


/R    表示递归 ,进入根目录树 [Drive:]Path,在树的每个目录中执行 for 语句。
如果在 /R 后没有指定目录,则认为是当前目录。
如果 Set 只是一个句点 (.),则只枚举目录树。
语法是:
FOR /R [[drive:]path] %%variable IN (set) DO command
上面我们知道,/d只能显示当前路径下的目录名字,那么现在这个/R也是和目录有关,
它能干嘛呢?放心他比/D强大多了!
它可以把当前或者你指定路径下的文件名字全部读取,注意是文件名字,有什么用看例子:
@echo off
for /r c:\ %%i in (*.exe) do @echo %%i
pause
我们把这个BAT保存到D盘,或者随便哪里都可以,然后执行,我会就会看到,
他把C盘根目录,和每个目录的子目录下面全部的EXE文件都列出来了,
这里的c:\就是目录了。

再来一个
@echo off
for /r %%i in (*.exe) do @echo %%i
pause
参数不一样了,这个命令前面没加那个C:\也就是搜索路径,
这样他就会以当前目录为搜索路径,
比如把这个BAT放在d:\test目录下执行,
那么他就会把d:\test目录和他下面的子目录的全部EXE文件列出来。

/L  表示迭代数值范围 ,使用迭代变量设置起始值 (Start#),
然后逐步执行一组范围的值,直到该值超过所设置的终止值 (End#)。
/L 将通过对 Start# 与 End# 进行比较来执行迭代变量。
如果 Start# 小于 End#,就会执行该命令。
如果迭代变量超过 End#,则命令解释程序退出此循环。
还可以使用负的 Step# 以递减数值的方式逐步执行此范围内的值。例如:
(1,1,5) 生成序列 1 2 3 4 5,
而 (5,-1,1) 则生成序列 (5 4 3 2 1)。

语法是:
for /L %% Variable in (Start#,Step#,End#) do Command

例如:
@echo off
for /l %%i in (1,1,5) do @echo %%i
pause
保存执行看效果,他会打印从1 2 3 4 5 这样5个数字
(1,1,5)这个参数也就是表示从1开始每次加1直到5终止!

再看这个例子
@echo off
for /l %%i in (1,1,5) do start cmd
pause
执行后是不是吓了一跳,怎么多了5个CMD窗口,
如果把那个 (1,1,5)改成 (1,1,65535)会有什么结果?
我先告诉大家,会打开65535个CMD窗口!
当然我们也可以把那个start cmd改成md %%i
这样就会建立指定个目录了,名字为1-65535
看完这个被我赋予破坏性质的参数后,我们来看最后一个参数

/f
含有/F的for有很大的用处,在批处理中使用的最多,用法如下:
格式:
FOR /F ["options"] %%i IN (file) DO command
FOR /F ["options"] %%i IN ("string") DO command
FOR /F ["options"] %%i IN ('command') DO command
这个可能是最常用的,也是最强的命令,主要用来处理文件和一些命令的输出结果。
file             代表一个或多个文件
string         代表字符串
command    代表命令
["options"]  可选

对于
FOR /F %%i IN (file) DO command
file为文件名,按照官方的说法是,for会依次将file中的文件打开,
并且在进行到下一个文件之前将每个文件读取到内存,
按照每一行分成一个一个的元素,忽略空白的行,看个例子:
假如文件a.txt中有如下内容:
第1行第1列 第1行第2列 第1行第3列
第2行第1列 第2行第2列 第2行第3列
第3行第1列 第3行第2列 第3行第3列
你想显示a.txt中的内容,会用什么命令呢?
当然是type,type a.txt
for也可以完成同样的命令:
for /f %%i in (a.txt) do echo %%i
还是先从括号执行,因为含有参数/f,
所以for会先打开a.txt,然后读出a.txt里面的所有内容,
把它作为一个集合,并且以每一行作为一个元素,所以会产生这样的集合,
{"第1行第1列 第1行第2列 第1行第3列", //第一个元素
"第2行第1列 第2行第2列 第2行第3列", //第二个元素
"第3行第1列 第3行第2列 第3行第3列"}   //第三个元素
集合中只有3个元素,同样用%%i依次代替每个元素,然后执行do后面的命令。
具体过程:
用%%i代替"第1行第1列 第1行第2列 第1行第3列",执行do后面的echo %%i,显示"第1行第1列 第1行第2列 第1行第3列",
用%%i代替"第2行第1列 第2行第2列 第2行第3列",执行echo %%i,显示"第2行第1列 第2行第2列 第2行第3列",
依次,直到每个元素都代替完为止。

为了加强理解/f的作用,请执行一下两个命令,对比即可明白:
for /f %%i in (a.txt) do echo %%i
这个会显示a.txt里面的内容,因为/f的作用,会读出a.txt中的内容。

for %%i in (a.txt) do echo %%i
而这个只会显示a.txt这个名字,并不会读取其中的内容。

通过上面的学习,我们发现for /f会默认以每一行来作为一个元素,
但是如果我们还想把每一行再分解更小的内容,该怎么办呢?
不用担心,for命令还为我们提供了更详细的参数,使我们将每一行分为更小的元素成为可能。
它们就是:delims和tokens
delims 用来告诉for每一行应该拿什么作为分隔符,默认的分隔符是空格和tab键
比如,还是上面的文件,我们执行下面的命令:
for /f "delims= " %%i in (a.txt) do echo %%i
显示的结果是:
第1行第1列
第2行第1列
第3行第1列
为什么是这样的呢。
因为这里有了delims这个参数,
=后面有一个空格,意思是再将每个元素以空格分割,默认是只取分割之后的第一个元素。
执行过程是:
将第一个元素"第1行第1列 第1行第2列 第1行第3列"
分成三个元素:"第1行第1列" "第1行第2列" "第1行第3列",
它默认只取第一个,即"第1行第1列",然后执行do后面的命令,依次类推。
但是这样还是有局限的,如果我们想要每一行的第二列元素,那又如何呢?
这时候,tokens跳出来说,我能做到。
它的作用就是当你通过delims将每一行分为更小的元素时,由它来控制要取哪一个或哪几个。
还是上面的例子,执行如下命令:
for /f "tokens=2 delims= " %%i in (a.txt) do echo %%i
执行结果:
第1行第2列
第2行第2列
第3行第2列
如果要显示第三列,那就换成tokens=3。
同时tokens支持通配符*,以及限定范围。
如果要显示第二列和第三列,则换成tokens=2,3或tokens=2-3,
如果还有更多的则为:tokens=2-10之类的。
此时的命令为:
for /f "tokens=2,3 delims= " %%i in (a.txt) do echo %%i %%j
怎么多出一个%%j?
这是因为你的tokens后面要取每一行的两列,
用%%i来替换第二列,用%%j来替换第三列。
并且必须是按照英文字母顺序排列的,
%%j不能换成%%k,因为i后面是j
执行结果为:
第1行第2列 第1行第3列
第2行第2列 第2行第3列
第3行第2列 第3行第3列
对以通配符*,就是把这一行全部或者这一行的剩余部分当作一个元素了。
比如:
for /f "tokens=* delims= " %%i in (a.txt) do echo %%i
执行结果为:
第1行第1列 第1行第2列 第1行第3列
第2行第1列 第2行第2列 第2行第3列
第3行第1列 第3行第2列 第3行第3列
其实就跟for /f %%i in (a.txt) do echo %%i的执行结果是一样的。
再如:
for /f "tokens=2,* delims= " %%i in (a.txt) do echo %%i %%j
执行结果为:
第1行第2列 第1行第3列
第2行第2列 第2行第3列
第3行第2列 第3行第3列
用%%i代替第二列,用%%j代替剩余的所有


最后还有skip合eol,这俩个简单,
skip就是要忽略文件的前多少行,
而eol用来指定当一行以什么符号开始时,就忽略它。
比如:
for /f "skip=2 tokens=*" %%i in (a.txt) do echo %%i
结果为:
第3行第1列 第3行第2列 第3行第3列
用skip来告诉for跳过前两行。
如果不加tokens=*的话,执行结果为:
第3行第1列
不知道怎么回事。
再如,当a.txt内容变成:
.第1行第1列 第1行第2列 第1行第3列
.第2行第1列 第2行第2列 第2行第3列
第3行第1列 第3行第2列 第3行第3列
执行for /f "eol=. tokens=*" %%i in (a.txt) do echo %%i结果是:
第3行第1列 第3行第2列 第3行第3列
用eol来告诉for忽略以"."开头的行。
同样也必须加tokens=*,否则只会显示"第3行第1列"。

评分

参与人数 1蝴蝶豆 +4 收起 理由
zero99 + 4 这个,,好长啊

查看全部评分

无薪税绵 回答时间:2018-3-5 15:21:20
因为For的功能太强大了。
加上解说和例子,
虽然长,但都是精华啊。

所属标签

相似问题

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
微信公众号二维码 微信公众号
手机版二维码 手机版