[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖

【练习-001】批处理实现两文本同行交替输出


从今天开始,本人将陆续推出文本输出类题目给新手做,并会根据解答思路和解答过程酌情
加分(解题思路为重),希望广大新手放开思路踊跃讨论和解题,本人也会在其中发表自己的
观点,并予以新人以指点的,好了不多说了,下面是第一题:


有两个文本如下(实际中并不知道两文本各有多少行):
文本1.txt
  1. aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
  2. ccccccccccccccccccccccccccccccccccccccc
  3. eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
  4. ggggggggggggggggggggggggggggggggggggggg
  5. wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
  6. zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
复制代码
文本2.txt
  1. hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
  2. iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
  3. jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
  4. nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn
复制代码
要求用批处理输出如下(两文本交替输出):
  1. aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
  2. hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
  3. ccccccccccccccccccccccccccccccccccccccc
  4. iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
  5. eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
  6. jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
  7. ggggggggggggggggggggggggggggggggggggggg
  8. nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn
  9. wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
  10. zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
复制代码
要求:
1 尽量不生成临时文件
2 代码要高效
3 代码尽量简洁
目的:
唯一的目的在于共同提高!
----------------------------------------------------------------------------------------------------------------------------------------------------
到目前为止,已经有了两个较为满意的答案:
第一种是先判断行数采用变量赋值的方法,见14楼more和15楼本人的代码。
特点:通用性强,代码简洁且效率较高。
第二种是不判断行数采用变量控制的方法,见16楼pusofalse版主和18楼本人的代码。
特点:通用性强,代码简洁且效率最高。

第三种是生成临时文件的方案,见24楼本人的代码。
特点:思路较独特
希望大家充分放开思路,看看还有别的解决方案不,只要是按要求做出来的,一律加分。



[ 本帖最后由 batman 于 2008-7-27 23:58 编辑 ]
***共同提高***

回复 1# batman


  这个问题我提问过的,版主用了5行代码就完成了工作。

TOP

  1. @echo off
  2. set /a m=1000,n=1001
  3. setlocal enabledelayedexpansion
  4. for /f "delims=" %%a in (a.txt) do set /a m+=2&set #!m!=%%a
  5. for /f "delims=" %%b in (b.txt) do set /a n+=2&set #!n!=%%b
  6. for /f "tokens=2 delims==" %%c in ('set #') do echo %%c
  7. pause
复制代码

TOP

  1. @echo off & setlocal enabledelayedexpansion
  2. cd /d %~dp0
  3. ::思路:通过行数定位结合more +n命令。
  4. set /a nn=0
  5. for /f "delims=" %%i in (1.txt) do (
  6. echo;%%i
  7. call :lp !nn! & set /a "nn+=1"
  8. )
  9. pause>nul & goto :eof
  10. :lp
  11. ::more 第一行是以0计数开始
  12. for /f "delims=" %%x in ('more +%1 2.txt') do echo;%%x & goto :eof
复制代码
我就是我,不一样的烟火!

TOP

  1. @echo off&setlocal enabledelayedexpansion
  2. (for /l %%a in (1,1,50) do set /p n%%a=)<1.txt
  3. (for /l %%a in (1,1,50) do set /p m%%a=)<2.txt
  4. for /l %%a in (1,1,50) do (
  5.     if not "!n%%a!"=="" echo;!n%%a!
  6.     if not "!m%%a!"=="" echo;!m%%a!
  7. )
  8. pause
复制代码

TOP

本帖最后由 zm900612 于 2011-7-18 20:27 编辑
  1. @echo off
  2. (for /f "delims=" %%a in (1.txt) do (
  3.     endlocal
  4.     echo;%%a
  5.     setlocal enabledelayedexpansion
  6.     set /p t2=
  7.     if defined t2 echo;!t2!
  8. ))<2.txt>合并.txt
  9. ::由于可以有两个不同的输入来源并存,所以双文本合并就成为轻而易举的事了
复制代码
1

评分人数

TOP

楼上说的是递归算法吗?
也就是先a,c交替得到ac
再b,d交替得到bd
再ac,bd交替得到abcd
这是需要文件数是二的乘方吧

另外这只是原型代码
真正实用还要考虑一些细节
比如文本的末行没有\r\n
天的白色影子

TOP

好办法,避开了多余的显示,省一个more。
其实如果文件数是2的倍数,还是可以这样用的,不过效率就难说了

TOP

49楼的代码刚看过
改了一个findstr
少了一个find
代码和思路都有创新
不过限于算法思想
对于两个以上的文本就无法实现交替输出了

另外
find /n /v "" 2.txt|more>tmp2 +2
可以改用
find /n /v "" <2.txt>tmp2
更好些
天的白色影子

TOP

41楼的改进思路,相信这能终结双文本同时输出的难题:
  1. @echo off
  2. findstr /n .* 1.txt>tmp1
  3. find /n /v "" 2.txt|more>tmp2 +2
  4. for /f "tokens=2*delims=]:" %%a in ('fc /lb1000 /n tmp1 tmp2^|sort') do echo;%%b
  5. del /q tmp?
  6. pause
复制代码

TOP

这是刚想到的,没41楼的巧妙
  1. @echo off
  2. (for /f "delims=" %%a in ('findstr /n .* a.txt') do echo [%%a)>ab.txt
  3. find /v /n "" b.txt|more>>ab.txt +2
  4. for /f "tokens=1* delims=:]" %%a in ('sort ab.txt') do echo;%%b
  5. pause
复制代码

[ 本帖最后由 zm900612 于 2011-2-22 18:17 编辑 ]

TOP

41楼的兄弟果然厉害,我也想到FC,但没想不出解决办法。
再想来,应该可以依靠类似“多线程”的方法来同时打开2个FOR来做文本读取,但控制输出顺序。
因为变量空间不同,必须依靠临时文件来做到这点,比如可以将控制信息写入流文件3.txt:ctrl.txt。

CMD要是能够实现内存映射,多进程使用公共变量就好了。。

TOP

回复 41楼 的帖子

本帖最近评分记录
zqz0012005 技术 +1 吃的盐多,过的桥多,老成精了 2010-1-14 12:44

这个评论果然中肯!这样的命令和用法也能联想到一起,还能奏奇效,不服不行!

TOP

高手啊弄多语句

TOP

  1. @echo off&setlocal enabledelayedexpansion
  2. for /f "tokens=1 delims=:" %%i in ('findstr /n .* a.txt') do set num1=%%i
  3. for /f "tokens=1 delims=:" %%i in ('findstr /n .* b.txt') do set num2=%%i
  4. if !num1! geq !num2! ( goto start
  5.   ) else (
  6.   ren  a.txt c.txt
  7.   ren  b.txt a.txt
  8.   ren  c.txt b.txt
  9. )
  10. :start
  11. set /a line=0
  12. for /f "delims=" %%a in (a.txt) do (
  13.     echo %%a
  14.     set /a c=0
  15.     for /f "delims=" %%b in ('more +!line! "b.txt"') do (
  16.     set /a c+=1
  17.     if !c! equ 1 echo %%b
  18.     )
  19.     set /a line+=1
  20. )
  21. pause>nul
复制代码
这个代码的缺陷在于每读取1.txt中一行都得把2.txt中内容遍历一次。但是我想不出办法让让读取2.txt的for只运行一个循环、用goto会出错。哎~~~

[ 本帖最后由 vincentzhou 于 2011-1-2 16:55 编辑 ]
only the strong survive!

TOP

返回列表