for /f 用法详解

来源:互联网 发布:苏芬战争 知乎 编辑:程序博客网 时间:2024/05/22 11:46

一、for /f 的基本用法
提取文本信息,则是for /f的拿手好戏:读取文件内容;提取某几行字符;截取某个字符片段;对提取到的内容再切分、打乱、杂糅……只要你所能想到的花样,for /f 都会想方设法帮你办到,因为,for /f 就是被设计成专门用于解析文本的。
例子:假如有个文本文件test.txt,内容如下:

无论:是文件、窗体、还是控件,在所有的非机器语言看来。无外乎都:是形如"c:test.txt"、"CWnd"之类的文本信息都只有:转化为具有一定格式的文本信息,方可被代码识别、操控

那么,将如下代码保存为test.cmd,并放在test.txt同一目录下运行,将会在屏幕上原样显示test.txt的内容:

@echo offfor /f  %%i in (test.txt) do echo %%ipause

以上代码是把内容一次性显示出来,下面的代码则会逐行显示:

@echo offfor /f %%i in (test.txt) do echo %%i&pausepause

二、切分字符串的利器:delims=
使用一下代码再次执行:

@echo offfor /f "delims=," %%i in (test.txt) do echo %%ipause

得到结果显示:

无论:是文件、窗体、还是控件无外乎都:是形如"c:\test.txt"、"CWnd"之类的文本信息都只有:转化为具有一定格式的文本信息

结果,惊奇地发现,每行第一个逗号之后的所有内容都不见了(如果有不存在逗号的行,则保留原样)。

在这里,我们引入了一个新的开关:"delims=,",它的含义是:以逗号作为被处理的字符串的分隔符号。
在批处理中,指定分隔符号的方法是:添加一个形如 "delims=符号列表" 的开关,这样,被处理的每行字符串都会被符号列表中罗列出来的符号切分开来。
需要注意的是:如果没有指定"delims=符号列表"这个开关,那么,for /f 语句默认以空格键或跳格键作为分隔符号。请把[txt1]中不同位置上的标点符号改为空格或跳格,再运行试试。

在上面的讲解中,我提到了指定分隔符号的方法:添加一个形如"delims=符号列表"的开关。以上是"符号列表"而非"符号",这是大有讲究的,因为,你也可以一次性指定多个分隔符号!

使用一下代码

@echo offfor /f "delims=、," %%i in (test.txt) do echo %%ipause

结果显示:

无论:是文件无外乎都:是形如"c:\test.txt"都只有:转化为具有一定格式的文本信息

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

三、定点提取:tokens=
for /f 默认只能提取到第一节的内容,如何提取不在第一节的内容。tokens= 后面一般跟的是数字,如 tokens=2,也可以跟多个,但是每个数字之间用逗号分隔,如 tokens=3,5,8,它们的含义分别是:提取第2节字符串、提取第3、第5和第8节字符串。注意,这里所说的“节”,是由 delims= 这一开关划分的,它的内容并不是一成不变的。
下面来看一个例子:test2.txt

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

要提取的内容在以逗号切分的第3节, 代码应该如下:

@echo offfor /f "delims=, tokens=3" %%i in (test.txt) do echo %%ipause

而要提取第2、5节内容,则代码如下:

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

运行批处理后发现,执行结果只显示了第2节的内容。
  原来,echo 后面的 %%i 只接收到了 tokens=2,5 中第一个数值2所代表的那个字符串,而第二个数值5所代表的字符串因为没有变量来接收,所以就无法在执行结果中显示出来了。
  那么,要如何接收 tokens= 后面多个数值所指代的内容呢?
  for /f 语句对这种情况做如下规定:
  如果 tokens= 后面指定了多个数字,如果形式变量为%%i,那么,第一个数字指代的内容用第一个形式变量%%i来接收,第二个数字指代的内容用第二个形式变量%%j来接收,第三个数字指代的内容用第三个形式变量%%k来接收……第N个数字指代的内容用第N个形式变量来接收,其中,形式变量遵循字母的排序,第N个形式变量具体是什么符号,由第一个形式变量来决定:如果第一个形式变量是%%i,那么,第二个形式变量就是%%j;如果第一个形式变量用的是%%x,那么,第二个形式变量就是%%y。

使用一下代码则显示第5节:

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

要求:显示[txt2]中的内容,但是逗号要替换成空格,如何编写代码

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

下面代码中最后最后两节用逗号分割

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

四、跳过无关内容,skip=n

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

@echo offfor /f "skip=2" %%i in (test.txt) do echo %%ipause

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

FOR /F "eol=; tokens=2,3* delims=, " %i in (myfile.txt) do @echo %i %j %k会分析 myfile.txt 中的每一行,忽略以分号打头的那些行……

for /f 语句是默认忽略以分号打头的行内容的,正如它默认以空格键或跳格键作为字符串的切分字符一样。(hello123world注:eol=;这种默认设置,在delims=;时变得无效。)
六、如何决定该使用 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 (……)

1、当你希望读取文本文件中的内容的话,第一个括号中不用任何符号包裹,应该使用的是第1条语句;例如:你想显示test.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 这样的语句;
3、当你要处理的是一个字符串的时候,第一个括号中的内容必须用双引号括起来,应该是用的是第3条语句;例如:当你想把bbs.bathome.net这串字符中的点号换为短横线并显示出来的话,可以使用 for /f "delims=. tokens=1-3" %%i in ("bbs.bathome.net") do echo %%i-%%j-%%k 这样的语句。
很显然,第一个括号里是否需要用符号包裹起来,以及使用什么样的符号包裹,取决于要处理的对象属于什么类型:如果是文件,则无需包裹;如果是命令语句,则用单引号包裹;如果是字符串,则使用双引号括起来。

当路径中含有特殊字符的时候,应该使用引号把路径括起来

下面有个例子,并配有简单的说明:
FOR /F "usebackq delims==" %i IN (`set`) DO @echo %i
会枚举当前环境中的环境变量名称。

你仔细对比了for /f语句使用usebackq和不使用usebackq时在写法上的差别,很快就找到了答案:当使用了usebackq之后,如果第一个括号中是一条命令语句,那么,就要把单引号'改成后引号`(键盘左上角esc键下面的那个按键,与~在同一键位上)。
usebackq 是一个增强型参数,当使用了这个参数之后,原来的for语句中第一个括号内的写法要做如下变动:如果第一个括号里的对象是一条命令语句的话,原来的单引号'要改为后引号`;如果第一个括号里的对象是字符串的话,原来的双引号"要改为单引号';如果第一个括号里的对象是文件名的话,要用双引号"括起来。

@echo offfor /f "usebackq" %%i in ("test 1.txt") do echo %%ipause

测试通过!

这时我们发现一条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 (……)