bat 笔记

cmd删除非空文件夹

rd+空格+/s/q+空格+d:\filedir

 

for语句的基本用法

在批处理文件中:

FOR %%variable IN (command1) DO command2 [command-parameters]

之所以要区分cmd窗口和批处理文件两种环境,是因为在这两种环境下,命令语句表现出来的行为虽然基本一样,但是在细节上还是稍有不同。
最明显的一个差异就是:在cmd窗口中,for之后的形式变量I必须使用单百分号引用,即%i;而在批处理文件中,引用形式变量i必须使用双百分号,即%%i。
为了方便起见,若不是特别强调,以下的讲解都以批处理文件环境为例。

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

 

 1、for语句的形式变量I,可以换成26个字母中的任意一个,这些字母会区分大小写,也就是说,%%I和%%i会被认为不是同一个变量;形式变量I还可以换成其他的字符,但是,为了不与批处理中的%0~%9这10个形式变量发生冲突,请不要随意把%%I替换为%%0 ~%%9中的任意一个;
   2、in和do之间的command1表示的字符串或变量可以是一个,也可以是多个,每一个字符串或变量,我们称之为一个元素,每个元素之间,用空格键、跳格键、逗号、分号或等号分隔;
   3、for语句依次提取command1中的每一个元素,把它的值赋予形式变量I,带到do后的command2中参与命令的执行;并且每次只提取一个元素,然后执行一次do后的命令语句,而无论这个元素是否被带到command2中参与了command2的运行;当执行完一次do后的语句之后,再提取command1中的下一个元素,再执行一次command2,如此循环,直到command1中的所有元素都已经被提取完毕,该for语句才宣告执行结束;

其中,第3点是最为关键的,它描述了for语句的执行过程,是for语句的精髓所在,大家一定要牢记这一条,才能深刻理解更为复杂的for流程。

 

for /f 用法详解

(一)为解析文本而生:for /f 的基本用法

无论for语句做何种变化,它的执行过程仍然遵循基本的for流程:依次处理每个元素,直到所有的元素都被处理为止。只不过在for /f语句中,这里的元素是指文件中的每一行,也就是说,for /f 语句是以行为单位处理文本文件的。这是一条极为重要的规则,在上一章中也强调过它的重要性,希望在接下来的学习过程中,你能时刻牢记这一原则,那么,很多问题将会迎刃而解。以下是验证这一说法的演示代码(在[code4]的基础上添加了&pause语句):

@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

 

 执行过程是:逐行读取test.txt中的内容,以点号和逗号切分每一行的内容(不存在点号和逗号的行,则不再切分,为了描述的方便,我们把被点号或逗号切分的一个一个的字符串片段,称之为节),然后,for /f 会提取第一节的内容作为最终结果,显示在屏幕上。需要注意的是,在这里,所有行的字符串被切分成了两个以上的节,但是,[code7]的代码只会提取第一节字符串的内容,因为 for /f 语句默认只提取第一节的符串。

 (三) 定点提取:tokens=

上一节在讲解 delims= 的时候,我一再强调 for /f 默认只能提取到第一节的内容,现在我们来思考一个问题:如果我要提取的内容不在第一节上,那怎么办?

[txt2]

尺有所短,寸有所长,学好批处理没商量,考虑问题复杂化,解决问题简洁化。

如果我们现在要提取的不只一个“节”,而是多个,那又怎么办呢?比如,要提取以逗号切分的第2节和第5节字符串,是写成这样吗?
[code9]

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

运行批处理后发现,执行结果只显示了第2节的内容。

如果 tokens= 后面指定了多个数字,如果形式变量为%%i,那么,第一个数字指代的内容用第一个形式变量%%i来接收,第二个数字指代的内容用第二个形式变量%%j来接收,第三个数字指代的内容用第三个形式变量%%k来接收……第N个数字指代的内容用第N个形式变量来接收,其中,形式变量遵循字母的排序,第N个形式变量具体是什么符号,由第一个形式变量来决定:如果第一个形式变量是%%i,那么,第二个形式变量就是%%j;如果第一个形式变量用的是%%x,那么,第二个 形式变量就是%%y。

 

 

假如要提取的“节”数不是5,而是10,或者20,或者更多,难道我也得从1写到10、20或者更多吗?有没有更简洁的写法呢?

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

还可以把这个表达式写得更复杂一点:tokens=1,2-5,tokens=1-3,4,5,tokens=1-4,5……怎么方便就怎么写吧。

[code12]

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

结果,第一个逗号不见了,取代它的是一个空格符号,其余部分保持不变。

[txt2] 的内容被切分,切分符号为逗号,当切分完第一节之后,切分动作不再继续下去,因为 tokens=1,* 中,星号前面紧跟的是数字1;第一节字符串被切分完之后,其余部分字符串不做任何切分,整体作为第二节字符串,这样,[txt2]就被切分成了两节,分别 被变量%%i和变量%%j接收。

[code13]

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

 

 (四) 跳过无关内容,直奔主题:skip=n

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

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

这段代码将跳过头两行内容,从第3行起显示test.txt中的信息。

 

(五) 忽略以指定字符打头的行:eol=

 在cmd窗口中敲入:for /?,相关的解释为:

eol=c    -指一个行注释字符的结尾(就一个)
FOR /F "eol=; tokens=2,3* delims=, " %i in (myfile.txt) do @echo %i %j %k
会分析 myfile.txt 中的每一行,忽略以分号打头的那些行……

第一条解释狗屁不通,颇为费解:行注释字符的结尾是什么意思?“(就一个)”怎么回事?结合第二条解释,才知道eol有忽略指定行的功能。但是,这两条解释是互相矛盾的:到底是忽略以指定字符打头的行,还是忽略以指定字符结尾的行?

 

(六)如何决定该使用 for /f 的哪种句式?(兼谈usebackq的使用)

for /f %%i in (……) do (……) 语句有好几种变形语句,不同之处在于第一个括号里的内容:有的是用单引号括起来,有的是用双引号包住,有的不用任何符号包裹,具体格式为:

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

当文件名含有空格等特殊符号时,用usebackq

 

这个时候,我们会吃惊地发现,区区一条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 (……)

其中,4、5、6由1、2、3发展而来,他们有这样的对应关系:1-->4、2-->5、3-->6。

 

 (七)变量延迟详解

 未完:https://www.cnblogs.com/adforce/p/3282591.html

 

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

四、翻箱倒柜遍历文件夹:for /r

 

(一)for /r 的作用及用法

[code21]

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

执行的结果如下所示:

d:\test\.
d:\test\1\.
d:\test\2\.
d:\test\3\.

类似与

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

执行的结果如下所示:(没有本目录)

d:\test\1\.
d:\test\2\.
d:\test\3\.


我们再回过头来归纳一下这个语句的作用:

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

上面语句的作用是:

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

 

 

 

 

 

 

 

 

posted @ 2019-10-17 14:14  QIYUEXIN  阅读(235)  评论(0编辑  收藏  举报