需求
现在有一个文件格式如图
ID 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
001 89.84 8.87 1.29 -0.0 0.0 68.99 0.0 0.0 4.67 1.48 0.0 0.0 14.69 0.0 0.0 0.0 0.01
002 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 99.99 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.01
003 0.0 0.0 0.0 0.0 99.99 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.01
需要把它的内容读出来,从第二行开始 (跳过第一行) 每一行用第一列作新文件名,把这一行的内容写进入。
代码实现
@echo off&setlocal EnableDelayedExpansion color 0a echo %date% %time% echo now...... set a=1 for /f "skip=1 tokens=1,* delims= " %%i in (pop.txt) do ( set "str=%%i.txt" echo !str! echo %%i %%j > !str! set /a a+=1 ) set /a a-=1 echo rename finish,rename count:%a%。 pause
新建成bat放入跟pop.txt同一个文件夹中点击运行
运行结果
运行结果如图
成功写入了文件。
查看文件内容
成功实现。
代码解析
除了一些时间和计数变量之外,关键实现的代码是这一句
for /f "skip=1 tokens=1,* delims= " %%i in (pop.txt) do ()
/f 代表的是读取的是一个文本文件,这样就会去读它的内容。
skip是跳过1行,从第二行开始
tokens表示取1列给%%i,*号表示取第一列之外的其他内容,这里第一列会给变量%%i,因为i后面的字母j,所以*号的内容会自动给%%j。
delims表示分隔符,我这里是tab分割的,反正直接粘贴文本中的复制进来就行了。
set "str=%%i.txt"
echo !str!
echo %%i %%j > !str!
这一段 用第一列构造文件名 然后把内容写入文件。
更多相似例子参考
假如文件a.txt中有如下内容:
第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
输出结果
第1行第1列 第1行第2列 第1行第3列
第2行第1列 第2行第2列 第2行第3列
第3行第1列 第3行第2列 第3行第3列
分割列
delims 用来告诉for每一行应该拿什么作为分隔符,默认的分隔符是空格和tab键
比如,还是上面的文件,我们执行下面的命令:
for /f "delims= " %%i in (a.txt) do echo %%i
显示的结果是:
第1行第1列
第2行第1列
第3行第1列
为什么是这样的呢。因为这里有了delims这个参数,=后面有一个空格,意思是再将每个元素以空格分割,默认是只取分割之后的第一个元素。
取第几列
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列”
扩展--每个文件保留第一行
@echo off&setlocal enabledelayedexpansion color 0a echo %date% %time% echo now...... set a=0 for /f "tokens=1,* delims= " %%i in (pop.source) do ( If !a!==0 ( echo %%i %%j set title=%%i %%j set /a a+=1 echo !title! ) else ( set "str=%%i.source" echo !str! echo !title! > !str! echo %%i %%j >> !str! set /a a+=1 ) ) set /a a-=1 echo rename finish,rename count:%a%。 pause
注意
@echo off&setlocal enabledelayedexpansion 设置成延迟变量 和 判断时用 !a!很重要。
而不是用 %a%来作判断。!a!才能反应变动。