Board logo

标题: 批处理中如何逐行读取文本并非将之设为变量? [打印本页]

作者: alfredhou     时间: 2006-4-5 05:19    标题: 批处理中如何逐行读取文本并非将之设为变量?

各位大哥,我是一名新手,想请教如何在批处理中逐行读取文本文件中的的信息并将之当成变量?例如,文件文件a.txt的内容为三行,分别是“123”、“456”、“789”,如何将它们逐一读出来,并将它赋值到三个变量A、B、C?即A=“123”,B=“456”,C=“789”?
作者: bagpipe     时间: 2006-4-5 09:13
for /f "tokens=*" %%i in (a.txt) do (set /a A=123&set /a B=456&set /a C=789)
作者: 3742668     时间: 2006-4-5 10:14
如果要完全达到楼主想要的效果的话,个人认为最好是启用扩展环境变量,然后在for里面设置自动递增,从而达到效果;另外可以直接在for里面用if语句来实现,缺点是代码比较冗余,可读性不是很好;另外还可以goto循环,每次用set /p var=<a.txt来读取,然后再把a.txt中已经读过的部分过滤掉,缺点是执行效率非常低,而且容错很差。
这样看来,似乎达到楼主的目的要花一番工夫了,其实不然,如果对各个命令都能了如指掌的话,利用各种命令的特性也可以变通地达到目的,比如findstr命令和find命令有个/n参数,可以在显示的查找结果每行前面加上行号,利用这个行号,也许能达到我们的要求。示例代码如下:
for /f "delims=: tokens=1,2" %i in ('"findstr /n . a.txt"') do set %i=%j
注意如果在批处理中运行上述代码时需先把%i更改为%%i,%j更改为%%j。
要点说明:
1,findstr显示的行号格式为    " 行号:内容    ",find的格式为 "[行号]内容",所以在delims中用冒号":"来分隔。
2,findstr后面的英文半角下句号“.”通配a.txt中的所有字符。
3,如果需要把变量定义到a中可以在后面加上一句set a=%1%,依次类推。
作者: alfredhou     时间: 2006-4-5 11:31
2楼可以注解一下吗?我是新手,看得不太懂。先谢谢啦
作者: alfredhou     时间: 2006-4-5 11:32
3楼能给出代码吗?我看不懂呀
作者: alfredhou     时间: 2006-4-5 11:51
问题是我如何才可以引用ABC的值?比如要把ABC的值加到B.TXT中去,如何实现?
作者: 3742668     时间: 2006-4-5 12:00
echo %1% >>b.txt
echo %2% >>b.txt
echo %3% >>b.txt
作者: alfredhou     时间: 2006-4-5 12:17
7楼,你的意思是不是2楼的代码再加上你的代码,即:
for /f "tokens=*" %%i in (a.txt) do (set /a A=123&set /a B=456&set /a C=789)
echo %1% >>b.txt
echo %2% >>b.txt
echo %3% >>b.txt

但出来的结果,在了b.txt中的内容是:
……(这部分是b.txt原先的内容)
ECHO 处于打开状态。
ECHO 处于打开状态。
ECHO 处于打开状态。

但我想要的结果是:
……(这部分是b.txt原先的内容)
123
456
789

怎么办?
作者: alfredhou     时间: 2006-4-5 12:23
7楼,谢谢啦。我弄明白啦。可以这样:
for /f "tokens=*" %%i in (a.txt) do (echo %%i >> b.txt)

太感谢大家啦
作者: alfredhou     时间: 2006-4-5 12:26
我虽然可以用这句达到目的,但我对这条命令理解不透彻,哪位可以注解一下给我吗?不胜感激
作者: alfredhou     时间: 2006-4-5 12:32
我主要是对/F “taken=*"不是很明白,哪位大哥愿意帮帮我
作者: 3742668     时间: 2006-4-5 12:48


  Quote:
Originally posted by alfredhou at 2006-4-5 05:19:
各位大哥,我是一名新手,想请教如何在批处理中逐行读取文本文件中的的信息并将之当成变量?例如,文件文件a.txt的内容为三行,分别是“123”、 ...

郁闷得紧,原来只是要追加而已,不是要赋值给变量。。
楼主告诉你一条更简单的:
type a.txt >>b.txt
作者: alfredhou     时间: 2006-4-5 14:23
是要赋值给变量啊,我的目的是要引用变量啊
作者: alfredhou     时间: 2006-4-5 14:42
3楼的代码好象运行不了。我在WIN2003上试
作者: 3742668     时间: 2006-4-5 14:48
1,你执行了for /f "tokens=*" %%i in (a.txt) do (echo %%i >> b.txt)这一句后你怎么分别引用A,B,C三个变量?
2,我的代码下面写得很清楚了,在批处理中运行时候要最修改,那只是在命令行中运行的,运行完毕后可以通过echo %1% %2% %3%来查看是否正确引用到了变量。
3,代码经过测试,确实可执行。
作者: alfredhou     时间: 2006-4-5 15:17
3楼的大哥不好意思,我原先没看懂,现在弄明白了,你的是可以执行的。但我现在还是不懂得如何去引用变量的值。我目的是想这样:
先在a.txt中读一行,然后在b.txt中搜索,如果没有这行的内容则添上去,有的话就略过。我发觉是我原先没有表达得准确。对不起。
另外,你提到可以用goto循环,我有点明白其中的思路,也就是先读取一行,然后针对性地跳到相应的程序段。但现在我的问题是我根本不知道如何才可以读取a.txt中的一行?
用FOR是读遍了才停的,我该怎么办?
先谢谢你啦
作者: Climbing     时间: 2006-4-5 18:09
是啊,很多时候把问题描述清楚是很重要的,如果你不知道如何描述问题的解决步骤,就把你想做什么说清楚。
作者: 3742668     时间: 2006-4-5 20:57
不是我不明白,而是这楼主变幻太快。。
呵呵,你的要求变化得大。。
不想用type的话那就试试findstr+type:
findstr /v /g:b.txt a.txt >>tmp.txt
type tmp.txt >> b.txt
未经测试,理论上行得通,我想这个方法相比前面的那个方法更适合你。
作者: wang6610     时间: 2006-4-6 01:09
有意思!
作者: willsort     时间: 2006-4-6 03:07
Re 3742668:

      估计楼主的变量,并非指环境变量,而是指for的替换变量,这样就好理解了。

      另外,你的代码确实富于技巧性,稍加修改即可用于提取文本中的指定行,是一个具有普遍意义的算法。
作者: alfredhou     时间: 2006-4-6 16:37    标题: re:3742668

RE:3742668
大哥,谢谢你!我测试过你的方法,事实证明是可行的!万分感谢!

此外,我在测试的时候遇到一些总是问题:

1) 如果a.txt和b.txt原先都是有内容的话,那运行第一次时结果是和预期目标一致的,但再运行多一次就不一致了。我后来发现是因为tmp.txt第一次是空的,而第二次则有内容了。于是我在你的代码后面加了一条:del tmp.txt

2)如果b.txt原先是全空没有内容的话,那么运行批处理之后它仍然是全空没有内容的,也就是说达不到预期的目标。当然,我可以事情加入一行毫不相干的内容,那就可以达到我的预期目标。但我觉得那不是正道。

请问你有什么更好的解决方法吗?
作者: alfredhou     时间: 2006-4-6 16:42    标题: RE:willsort

RE:willsort
版主你好!
你说稍加改造可以提取指定的行,可以予以明示吗?我是一个新手,实在想不出来怎么才可以实现这个目标?

findstr /v /g:b.txt a.txt >>tmp.txt
type tmp.txt >> b.txt

请告诉我改造后的代码吗?

谢谢
作者: 3742668     时间: 2006-4-6 18:34
寒一个先。
其实你想实现的东东几篇回贴里面都有了,只不过你没能把它们结合起来而已。
关于你的问题:
1) 这个不算问题。
2) 用set /p tmpvar=<b.txt来获得,然后用if defined tmpvar来判断是否为空

最后,再汗一个,willsort说的稍加改造并非指的是type+findstr的那段,而是前面的for,呵呵,建议你多翻翻老贴多运行command /?。
作者: ke     时间: 2006-10-2 17:08
好帖,3742668版主真是热心!