Board logo

标题: 再谈批处理最大原样输出文本字符 [打印本页]

作者: batman    时间: 2011-2-24 10:49     标题: 再谈批处理最大原样输出文本字符

原文由本人同时发表在个人qq空间:http://user.qzone.qq.com/841615149/blog/1298514537
      其实在cn-dos的《最大原样输出文本字符》一贴中通过各位大哥级人物的共同努力早就解决了这一难题,本人只是以个人的理解再归纳总结一次,以便新人更好地消化吸收。

  首先,我们先来谈谈如何输出带有空行(空行也要输出)的文本。大家知道for命令是默认忽略空行的,也就是说文本中的空行用for.....echo的方式是不会得到输出的。那么如何解决这一问题呢?这时findstr就大显身手了:
  1. @echo offf
  2. for /f "tokens=1,2 delims=:" %%a in ('findstr /n .* a.txt') do echo,%%b
  3. pause>nul
复制代码
  findstr /n .* a.txt能将a.txt的内容全部打印出来,但是前面都加上了行号和:字符,于是我们通过设置:为分隔符就可以将这个输出结果每行分成两列,第一列是行号,第二列就是a.txt原来每行的内容,我们只取第二列即可。事实上这种方法能几乎兼容所有的特殊字符,但它还是存在一个硬伤。大家猜猜是什么呢?其实这个硬伤就在于它是用:字符来做为每行的分隔符,那么当文本内容中含有:字符的时候,:字符将全部视为分隔符,同样只能输出行号后的:字符和文本行第一个:字符之间的内容,这时我们也可以修改上面的代码为:
  1. @echo offf
  2. for /f "tokens=1* delims=:" %%a in ('findstr /n .* a.txt') do echo,%%b
  3. pause>nul
复制代码
  

  但即使如此,还是不能解决a.txt中有的行是以:字符打头的情况(这个打头的:字符将不被输出)。那么,我们又该怎么办呢?大家记不记得set str="%str:*a=%"这个替换方法,就是将str字串符中从打头字符到第一个a字符之间的所有字符替换为空(包含a字符)。我们也可以用这种方法来处理这个讨厌的:字符:
  1. @echo off&setlocal enabledelayedexpansion
  2. for /f "delims=" %%a in ('findstr /n .* a.txt') do (
  3.      set "str=%%a"
  4.       echo,!str:*:=!
  5. )
  6. pause>nul
复制代码
  哈哈,难缠的:字符终于被彻底征服了。可是,我们可别高兴得太早哦,这时又跳出来一个捣蛋的家伙!。不信的话你拿着上面的代码去处理含有!的文本看,你会发现文本中所有的!没有被输出,如果出现!******!的情况,就连两个!字符间的所有的字符都不会被输出。这是因为开启变量延迟后,!将当做逃逸字符被脱去,而两个!字符之间的字符将被视为变量处理,而输出这个变量的值(空值)。真的是一波刚平一波又起啊,难道这个:字符和!字符是生死冤家,不能被同屏输出?答案肯定是否。是的,我们通过预处理就可以轻松解决这一问题:
  1. @echo off
  2. for /f "delims=" %%a in ('findstr /n .* a.txt') do (
  3.     set "str=%%a"
  4.     setlocal enabledelayedexpansion
  5.     echo,!str:*:=!
  6.     endlocal
  7. )
  8. pause>nul
复制代码
  至此,我们已经完全解决同时正确输出有空行和所有特殊字符(不包括不可见字符)的文本这一问题了。但有一点还要说明一下,就是这个echo,!str:*:=!之所以在echo后面加上,是为了输出空行,而平常时我们常用到echo.!str! echo/!str!这些用法来输出空行,但在这里只能用到,字符才能正确输出,不信的话,大家可以自己测试下。

[ 本帖最后由 batman 于 2011-2-24 11:00 编辑 ]
作者: batman    时间: 2011-2-24 11:13

补充说明:
  如果只是要原样输出文本,建议用type a.txt和findstr .* a.txt即可,
  但如果在原样输出文本,还要对文本字符进行处理的话,就要用
  到本贴所说的方法了。
作者: Batcher    时间: 2011-2-24 11:49

除了逗号之外,分号和等号也行吧?
作者: wc726842270    时间: 2011-2-24 12:30

刚才测试了一下。除了两位大老的方法外,退格也行。不过得在其前加个空格
  1. setlocal enabledelayedexpansion
  2.     echo !str:*:=!
  3.     endlocal
复制代码

作者: batman    时间: 2011-2-24 14:36     标题: 回复 3楼 的帖子

确实分号和等号可以。。。
作者: dennis1314    时间: 2011-2-25 16:24

刚试了下,最后成功显示出来
作者: ai20110304    时间: 2018-8-28 10:44

从第三条涨知识
作者: qixiaobin0715    时间: 2020-7-22 19:36

没想到近来我也用到了原样输出文本的知识,谢谢版主!!!
作者: ANSL    时间: 2022-11-4 20:46

谢谢楼主,学习了!




欢迎光临 批处理之家 (http://bbs.bathome.net/) Powered by Discuz! 7.2