Board logo

标题: (已结)如何使用FOR命令显示文件中每行的前10个字符 [打印本页]

作者: treey     时间: 2005-7-27 09:00    标题: (已结)如何使用FOR命令显示文件中每行的前10个字符

在纯DOS下如何使用FOR命令显示文件中每行的前10个字符

---------- Edited by willsort ----------
LMOD 的方案在12楼和14楼
FOR(NT's) 的方案在16楼
---------- Edited by willsort ----------


[ Last edited by willsort on 2005-8-2 at 20:06 ]
作者: willsort     时间: 2005-7-27 14:00
Re treey:

  在纯DOS下不使用第三方工具完成文本的控制比较复杂,就目前情况来看,必须实现文本的行遍历,这个你可以在我以前的旧帖中见到一些范例(使用关键字“遍历”查询);另外,实现单行的文本控制,一般使用debug,在此我们可以用他控制文件的固定长度来达到目标。比如,有某行为0123456789123456,可以用行遍历得到内容为 “echo 0123456789123456” 临时批处理,此时用debug脚本修改这个批处理长度为15个字节(字符串长10+echo+空格),此时执行它即可得到想要的字符串了。

  当然,使用第三方工具会简单很多,但那不是我的擅长,你可以试试strings.com这个小程序,在本站MSDOS7.1启动盘中有下载。

  如果在XP或NT命令行下,可以使用FOR的行遍历特性+SET的串截取特性来实现类似的功能。

[ Last edited by willsort on 2005-7-27 at 17:43 ]
作者: treey     时间: 2005-7-27 16:34
哦,谢谢willsort大侠.我试试!
作者: treey     时间: 2005-7-29 17:52
MSDOS7.1中没有strings,只有LMOD.
作者: JonePeng     时间: 2005-7-29 21:33
不知楼主的MSDOS 7.1是哪个版本?Wengier的MSDOS 7.1超级启动盘就有strings.com,而没有LMOD。
作者: willsort     时间: 2005-7-29 22:03
Re treey:

  我说的是MSDOS7.1的启动盘,就是 Wengier 主编的那个超级通用启动盘,工具丰富是它的一大特点。而你所说的是MSDOS7.1的安装盘,兼容于原MSDOS则是最大特点,而鉴于版权问题,很多非MS的软件是无法考虑的。

  另外,关于ANSI的转义字符,我已经说过了,请查阅DOS帮助文档中ANSI的有关部分,比如你帖子中提到的MSDOS7.10安装版,在其中输入DOSHELP就可以查看相关帮助了。
作者: treey     时间: 2005-7-30 10:03
哦,好的.strings已找到.但用法还不是很了解.谢谢willsort大侠!
作者: treey     时间: 2005-7-30 10:35
能不能具体讲解一下strings的用法,或是有示例.
作者: willsort     时间: 2005-7-30 11:59
Re treey:

  学习任何知识,个人的主观能动性都是第一要素。

  对于 strings.com 的用法,你只要用(strings /? 和 strings help 对应的子命令)查看一下它的帮助信息,即可得到初步的印象,然后你再有的放矢的提出问题,掌握知识的效率将会快很多。

  对你的问题而言,使用 left 子命令是我最优先的考虑,但是经过实际测试以后,我发现它擅长处理单个字符串然后保存结果到环境变量,但无法高效的处理整个文本流,所以使用它将还是一个比较复杂的过程。

  而从文本流我立即联想到,LMOD就是个很优秀的文本流处理工具,马上查阅它的帮助信息(lmod /?),发现确实很简单地就实现了你所需要的功能。至于如何实现,我希望你能经历一个类似的研究探索过程,相信对你的帮助会很大。

  毛主席说过,没有调查研究就没有发言权,这句话对你我都适用。

[ Last edited by willsort on 2005-7-30 at 12:01 ]
作者: treey     时间: 2005-8-1 08:39
我试了很多遍但是命令都没有被执行,就象执行了死循环,每次都要中断程序.不知道为什么?连在每行第8个字符插入aaa字符都不能运行.lmod /l 8 "aaa"还请willsort大侠看一下命令是否有误,还是DOS环境的设置有问题.
作者: willsort     时间: 2005-8-1 10:10
Re treey:

  从你的使用情形来看,你对 LMOD 语法的理解还有一定的距离。举例来说:

  在文件test.txt每行第8个字符插入aaa并输出到屏幕上:

  lmod /l* [1,8]aaa[9] <test.txt

  /l* 表示选择文本流所有的行,*是不可省略的,它前面可以加一个行号,表示选择从第几行开始,其前面的内容将被忽略;
  [1,8] 表示从文本流每一行的第1个字符起引用8个字符;
  aaa 表示你要插入的内容,不带引号;如果含有重定向等命令行特殊符号,可以使用["<|>"]的形式,引号将被自动剔除;
  [9] 表示从文本流每一行的第9个字符起引用其后所有的字符。

  <test.txt,表示引用的文本流内容来自文件test.txt的重定向输入;它也可以通过命令的管道流入,比如dir | lmod ......可以用LMOD处理DIR命令的信息;如果省略,则LMOD的文本流的源将是标准控制台(相当于 <con),也就是键盘,你所遇到的“死循环”,实际上就是等待你从键盘上输入文本内容,它是以Ctrl+Z作为结束标志的。

  从上帖的使用来看,你可能需要掌握一些关于文本流、控制台、重定向、管道方面的基础知识,这样对你的理解有很大帮助。

  至于,主楼的问题,相信你现在应该可以拿出你的答案了。
作者: treey     时间: 2005-8-1 13:05
谢谢willsort!问题已经解决.但是我发现使用了lmod命令之后,就不能简单使用管道命令将经过lmod编译过的屏幕内容输出到我要的文档中.例如lmodtest.bat   :lmod /l* [1,10] < a.txt 就不能用lmodtest > b.txt  请问这是什么原因?
作者: treey     时间: 2005-8-1 13:07
还有哪里有关于文本流、控制台、重定向、管道方面的基础知识...能否提供呢?感激不尽!
作者: willsort     时间: 2005-8-1 14:47
Re treey:

  

  Quote:
使用了lmod命令之后,就不能简单使用管道命令将经过lmod编译过的屏幕内容输出到我要的文档中

  看来你还没有彻底明白重定向输入输出以及命令管道是怎么回事,“输出到我要的文档中”正是我在上帖中有意留给你思考的问题,但谁知你竟是在重定向了lmodtest.bat的输出,而非lmod.com的输出,请使用:

  lmod /l* [1,10] < a.txt > b.txt

  Quote:
lmodtest.bat   :lmod /l* [1,10] < a.txt 就不能用lmodtest > b.txt

  是因为lmodtest是批处理程序,它输入输出方式是比较特殊的(很有可能是没有独立的输入输出句柄,猜测……),因此不能被重定向。当然,使用特殊的方法仍然可以得到它的输出,比如:

  %comspec% /c lmodtest.bat > b.txt

  但此时,我们重定向的是 command 或者 cmd 的输出,而非 lmodtest.bat 的,虽则它们的内容毫无二致。

  

  Quote:
还有哪里有关于文本流、控制台、重定向、管道方面的基础知识

  我不知道你是否曾认真查阅过MSDOS6.22(Help)/MSDOS7.10(DOSHELP)/WinNT's(帮助中“命令行概述”一节)的帮助文档。如果有过,你会找到很详尽的答案。

[ Last edited by willsort on 2005-8-1 at 14:51 ]
作者: treey     时间: 2005-8-1 15:00
哦,的确,我刚开始接触DOS及batch,只知道一些凤毛鳞角,还没看完doshelp.我马上去看看.再次感谢!
作者: willsort     时间: 2005-8-1 15:14
Re treey:

  最后,为了回应主楼的问题原意,以这个FOR命令版的显示控制例程作为结帖。至于纯DOS下的遍历程序,恕我没有太多的精力了。
:: Disp10.bat - A sample of display 10 characters of front of echo line
:: Will Sort - 14:57 2005-8-1
:: Note: 文中的字符包括中文和英文字符,并且一个中文字算一个字符而非两个
@echo off
if "%1"=="" cmd /v:on /c %0 cmdshell & goto :EOF
if exist test2.txt del test2.txt
for /f "tokens=*" %%a in (test1.txt) do (
    set line=%%a
    echo !line:~0,10!>> test2.txt
)
set line=