Board logo

标题: 【练习-001】批处理实现两文本同行交替输出 [打印本页]

作者: batman    时间: 2008-7-24 00:29     标题: 【练习-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 编辑 ]
作者: 浅默    时间: 2008-7-24 05:56

@echo off
for /f "tokens=1* delims=:" %%i in ('findstr /n .* 1.txt') do (
    echo %%j>>3.txt
    for /f "tokens=1* delims=:" %%a in ('findstr /n .* 2.txt') do (
        if %%i==%%a echo %%b>>3.txt
    )
)   
pasle
作者: batman    时间: 2008-7-24 08:05

首先对二楼做为鼓励予以加分,同时对存在的问题予以指出:
二楼的方法存在以下的问题:
1 首先我们不知道两个文本各有多少行,如果1.txt的行数比2.txt少,而你的代码中for循环到
了1.txt最后一行就终止了,那么2.txt多出的行就全部漏掉了。
2 如果1.txt中的行数比2.txt少,二楼的代码也存在效率问题,在上面的代码中调用for的次数
是1.txt行数乘上2.txt的行数,而理论上最少的调用次数是两文本行数的和。
3 if %%i==%%a改为if "%%i"=="%%a"实为妥当些。
4 最后的pause出现了笔误。

[ 本帖最后由 batman 于 2008-7-24 15:25 编辑 ]
作者: 随风    时间: 2008-7-24 13:38

纠正一点,2楼并没有产生临时文件,他只是输出到文件,不算违规。
此题,说难不难,说简单也不简单,不过以“浅默”的功力似乎不应该只是如此。。。
大家都来试试。。。看谁最先给出完美答案。。







.
作者: batman    时间: 2008-7-24 15:26

原帖由 随风 于 2008-7-24 13:38 发表
纠正一点,2楼并没有产生临时文件,他只是输出到文件,不算违规。

对不起,是我搞错了,已更正。
作者: pusofalse    时间: 2008-7-25 00:01

这题应该是1.txt总是比2.txt多吧?
作者: 随风    时间: 2008-7-25 00:21

原帖由 pusofalse 于 2008-7-25 00:01 发表
这题应该是1.txt总是比2.txt多吧?


未必,也有可能是 2.txt 比 1.txt 的行数多。
作者: batman    时间: 2008-7-25 00:35

给个小提示:
可以先判断两个文本哪个的行数多,再把行多的文本放到第一个for中。

同时也可以不判断文本的行数,但思路就要开放点了。

本人暂时想出了三个解决方案,暂不贴出,希望大家能有更好的办法。
作者: pusofalse    时间: 2008-7-25 00:36

这类的交错输出的文本题比较经典,不确定到底那个多,岂不是要先得读出行数多或行数少的那个?
作者: batman    时间: 2008-7-25 00:44

是不是可以换个思路:判断和输出同时进行呢?
作者: 随风    时间: 2008-7-25 00:49

也可以根本不必要判断文本的行数。
作者: pusofalse    时间: 2008-7-25 01:10

的确如此 思维定向了。
作者: youxi01    时间: 2008-7-25 08:23

不过有个疑问就是:效率是不是会非常低呢?特别是遭遇大文件时
根据代码的意思,似乎是查询两个文件行号一样的时候就分别写入到文件里

这样的话,要是第二个文件有1W行岂不是要比对1W次?这样,明显有9999次是没有必要的...
作者: more    时间: 2008-7-25 10:38     标题: 想得头都要破了

  1. @echo off
  2. setlocal enabledelayedexpansion
  3. for /f "delims=" %%a in ('type 11.txt') do (
  4.    set /a m+=1
  5.    set "home!m!=%%a"
  6. )
  7. for /f "delims=" %%b in ('type 12.txt') do (
  8.    set /a n+=1
  9.    set "bat!n!=%%b"
  10. )
  11. if %m% gtr %n% (
  12.    for /l %%c in (1 1 %m%) do (
  13.       if not "!home%%c!"=="" echo !home%%c!
  14.       if not "!bat%%c!"=="" echo !bat%%c!
  15.    )
  16. ) else (
  17.    for /l %%d in (1 1 %n%) do (
  18.       if not "!home%%d!"=="" echo !home%%d!
  19.       if not "!bat%%d!"=="" echo !bat%%d!
  20.    )
  21. )
  22. pause
复制代码

[ 本帖最后由 more 于 2008-7-25 10:44 编辑 ]
作者: batman    时间: 2008-7-25 11:40

原帖由 more 于 2008-7-25 10:38 发表
@echo off
setlocal enabledelayedexpansion
for /f "delims=" %%a in ('type 11.txt') do (
   set /a m+=1
   set "home!m!=%%a"
)
for /f "delims=" %%b in ('type 12.txt') do (
   set /a n+=1
   set  ...

代码可以简化,下面先公布我的第一种方法:
  1. @echo off
  2. for /f "delims=" %%i in (1.txt) do set /a n+=1&call,set "_%%n%%=%%i"
  3. for /f "delims=" %%i in (2.txt) do set /a m+=1&call,set ".%%m%%=%%i"
  4. if %n% gtr %m% (set "num=%n%") else (set "num=%m%")
  5. for /l %%i in (1,1,%num%) do (
  6.      if defined _%%i call,echo %%_%%i%%
  7.      if defined .%%i call,echo %%.%%i%%
  8. )
  9. pause>nul
复制代码

[ 本帖最后由 batman 于 2008-7-25 17:05 编辑 ]
作者: pusofalse    时间: 2008-7-25 16:44

@echo off&setlocal enabledelayedexpansion&set n=-1
for /f "delims=" %%a in (1.txt) do (
set/a n+=1
set flag=
call :lp %%a
if not defined flag echo %%a
)
:lp
if "%1" equ "" set/a n+=1
set m=skip=%n%
if "%m%" equ "skip=0" set "m="
for /f "%m% delims=" %%a in (2.txt) do if "%1" neq "" (echo %1&echo %%a&set flag=a&goto :eof) else echo %%a
if "%1" equ "" pause

[ 本帖最后由 pusofalse 于 2008-7-25 16:55 编辑 ]
作者: batman    时间: 2008-7-25 16:46

原帖由 youxi01 于 2008-7-25 08:23 发表
不过有个疑问就是:效率是不是会非常低呢?特别是遭遇大文件时
根据代码的意思,似乎是查询两个文件行号一样的时候就分别写入到文件里

这样的话,要是第二个文件有1W行岂不是要比对1W次?这样,明显有9999次是没 ...

我想在这里应该不有去考虑极端情况,比如特殊字符处理什么的。
作者: batman    时间: 2008-7-25 17:24

既然这种最高效的方法也出来了(只可惜是版主级做出来的),下面就贴出本人的第二种方法:
  1. @echo off
  2. set "n=-1"&set "flag=a"
  3. :begin
  4. set /a n+=1
  5. if %n% equ 0 (set "m=") else (set "m=skip=%n%")
  6. for /f "%m% delims=" %%i in (1.txt) do echo %%i&if defined flag goto next
  7. set no=a
  8. :next
  9. for /f "%m% delims=" %%i in (2.txt) do echo %%i&goto begin
  10. if not defined no set "flag="&goto begin
  11. pause>nul
复制代码

作者: pusofalse    时间: 2008-7-25 17:34

为了减少不必要的调用,修改如下。
  1. @echo off&set n=-1
  2. for /f "delims=" %%a in (1.txt) do (
  3. set/a n+=1
  4. set flag=
  5. if not defined faith call :lp %%a
  6. if not defined flag echo %%a
  7. )
  8. :lp
  9. if "%1" equ "" set/a n+=1
  10. set m=skip=%n%
  11. if "%m%" equ "skip=0" set "m="
  12. for /f "%m% delims=" %%a in (2.txt) do if "%1" neq "" (echo %1&echo %%a&set flag=a&goto :eof) else echo %%a
  13. set faith=faith
  14. if "%1" equ "" pause
复制代码

作者: batman    时间: 2008-7-25 18:16

再次提示:
第三种方法可就本题而言来解(不考虑行数太多的情况)
作者: 浅默    时间: 2008-7-25 19:25

@echo off
for /f "tokens=1* delims=:" %%i in ('findstr /n .* 1.txt') do set _%%i=%%j
for /f "tokens=1* delims=:" %%k in ('findstr /n .* 2.txt') do set _%%k.%%k=%%l
for /f "tokens=1* delims==" %%i in ('set _ ') do echo %%j
pause
要是就本题的几行上面的还行
作者: namejm    时间: 2008-7-25 20:56

  把两个文本的相同行交叉合并,需要考虑以下两种情况:
  1、两个文本的行数相同;
  2、两个文本的行数不同。

  如果两个文本行数相同,则可以省略对文本行数的判断,但考虑到效率高低,需要使用临时文件,则可使用如下代码:
  1. @echo off
  2. findstr .* 1.txt>_1.txt
  3. setlocal enabledelayedexpansion
  4. for /f "delims="  %%i in (2.txt) do (
  5.     set /a num+=1
  6.     echo !num!:%%i
  7.     findstr /b /i "!num!:" _1.txt
  8. )
  9. del /q _1.txt
  10. pause
复制代码
  如果两个文本行数不同,则需要判断行数谁多谁少,从而减少对比次数,演示代码如下:
  1. @echo off
  2. :: 生成临时文件,主要是为了获得 行数:行内容 格式的文本
  3. findstr /n .* 1.txt>_1.txt
  4. findstr /n .* 2.txt>_2.txt
  5. :: 获取各自的总行数
  6. for /f "delims=:" %%i in (_1.txt) do set num_1=%%i
  7. for /f "delims=:" %%i in (_2.txt) do set num_2=%%i
  8. :: 比较行数谁多谁少
  9. set num=%num_1%
  10. set file_1=_1.txt&set file_2=_2.txt
  11. if %num_1% geq %num_2% (
  12.     set num=%num_2%
  13.     set file_1=_2.txt&set file_2=_1.txt
  14. )
  15. :: 以行数少的文本为标准,交叉输出两文本的同行内容
  16. for /f "tokens=1* delims=:" %%i in (%file_1%) do (
  17.     echo %%i:%%j
  18.     findstr /b /i "%%i:" %file_2%
  19. )
  20. :: 对多出的行内容,一次性输出,减少了对比次数,从而提高效率
  21. more +%num% %file_2%
  22. del /q _1.txt _2.txt
  23. pause
复制代码
  如果不动用临时文件,要么需要设置大量的变量,严重消耗系统内存;要么需要用 if 语句对行号进行机械对比,严重影响效率;如果使用 set 排序方案,则要求每个文本的总行数不能超过9行,并且不能保证某个文件的行内容总是排在两行中的第一行或第二行。
  注:以上代码都没有考虑特殊字符。
作者: pusofalse    时间: 2008-7-25 21:09

jm厉害,考虑这么全面。
作者: batman    时间: 2008-7-26 20:39

最后给出本人的第三个方案,生成临时文件且通用性不很强,
解题思路和上面的完思路不同:
  1. @echo off&setlocal enabledelayedexpansion
  2. set "num=0"
  3. for %%a in (1.txt 2.txt) do (
  4.     for /f "delims=" %%i in (%%a) do (
  5.         set /a n+=1
  6.         if !n! gtr !num! set "num=!n!"
  7.         set /p=%%i <nul>>temp.txt
  8.     )
  9.     echo.>>temp.txt&set "n=0"
  10. )
  11. :lp
  12. set /a n+=1
  13. for /f "tokens=%n%" %%i in (temp.txt) do echo %%i
  14. if %n% neq %num% goto lp
  15. del /q temp.txt&pause>nul
复制代码

作者: keen    时间: 2009-4-16 19:56

我的,有点晚:
  1. @echo off&setlocal enabledelayedexpansion
  2. set m=-1
  3. for /f %%i in (1.txt) do set /a m+=2&set _!m!=%%i
  4. for /f %%j in (2.txt) do set /a n+=2&set _!n!=%%j
  5. if %m% gtr %n% (set max=%m%) else (set max=%n%)
  6. for /l %%k in (1 1 %max%) do (
  7.     if defined _%%k call,echo %%_%%k%%
  8. )
  9. pause
复制代码

作者: keen    时间: 2009-4-16 20:11

batman就是强!
我的跟batman的第一种方法(15楼)基本一样了。
batman的第二种方法(见18楼),更是高手典范。
作者: batman    时间: 2009-4-20 08:10

呵呵,本人最老的一道题也被你们翻出来了,加油,有这股劲就对了!
作者: netbenton    时间: 2009-4-29 23:06

  1. @echo off&setlocal enabledelayedexpansion
  2. for /f "delims="  %%a in (1.txt) do (set /a n+=1&set #!n!=%%a)
  3. for /f "delims=" %%a in (2.txt) do (
  4.     set/a m+=1
  5.     echo %%a
  6.     if defined #!m! for %%b in (!m!) do echo !#%%b!
  7. )
  8. set/a m+=1
  9. for /l %%a in (!m!,1,!n!) do echo !#%%a!
复制代码

作者: everest79    时间: 2009-4-30 02:15

一百行以内
  1. @echo off
  2. for /f "tokens=1* delims=[]" %%a in ('find /v /n "" ?.txt^|findstr /b "\[[0-9]\]"^|sort') do echo.%%b >>out.txt
  3. for /f "tokens=1* delims=[]" %%a in ('find /v /n "" ?.txt^|findstr /b "\[[0-9][0-9]\]"^|sort') do echo.%%b >>out.txt
  4. pause
复制代码

作者: netbenton    时间: 2009-4-30 07:38

楼上的不一定会交替的吧?
有可能会这样的
a.txt  行
b.txt  行
b.txt  行
a.txt  行
作者: abc001    时间: 2009-4-30 08:26     标题: 我也贴个

  1. @echo off
  2. setlocal enabledelayedexpansion
  3. for /f "delims=" %%a in ('type 1.txt') do set /a a+=1
  4. for /f "delims=" %%a in ('type 2.txt') do set /a b+=1
  5. set /a t1+=!a!-!b!
  6. set /a t2+=!b!-!a!
  7. for /f "delims=" %%a in ('type 1.txt') do (
  8. set m=
  9. set /a n+=1
  10. for /f "delims=" %%b in ('type 2.txt') do (
  11. set /a m+=1
  12. if "!n!" == "!m!" (
  13. echo %%a
  14. echo %%b
  15. )
  16. )
  17. )
  18. if !a! gtr !b! more 1.txt +!t1!
  19. if !a! lss !b! more 2.txt +!t2!
  20. )
  21. pause
复制代码

作者: inittab    时间: 2009-4-30 10:22

兼容两文件行数不同情况。
  1. @echo off&setlocal enabledelayedexpansion
  2. set/a n=0,m=0
  3. for /f "delims=" %%a in (2.txt) do set/a n+=1&set #!n!=%%a
  4. for /f "delims=" %%a in (1.txt) do (
  5. set/a m+=1
  6. if defined #!m! (echo %%a&call echo %%#!m!%%) else echo %%a
  7. )
  8. set /a m+=1
  9. if !n! gtr !m! for /l %%i in (!m!,1,!n!) do echo !#%%i!
  10. pause
复制代码

作者: everest79    时间: 2009-4-30 20:07

原帖由 netbenton 于 2009-4-30 07:38 发表
楼上的不一定会交替的吧?
有可能会这样的
a.txt  行
b.txt  行
b.txt  行
a.txt  行

  1. for /l %%i in (1,1,40) do (
  2. echo A:%%i >>a.txt
  3. echo B:%%i>>b.txt
  4. )
复制代码


你试了没有
作者: netbenton    时间: 2009-4-30 23:34     标题: re 36楼

是我搞错了,呵呵,没注到前面的是find,而不是findstr


君的方法,不知道这样是不是可以不限行数了呢:
find /v /n "" ?.txt |findstr "[ ]"|sort
作者: defanive    时间: 2009-5-1 00:29     标题: 也来试试

自己写了一个,感觉前两行速度有点慢,其他都很快,利用for /f加goto偷鸡。。。
  1. @echo off
  2. set /p line1=<1.txt&set /p line2=<2.txt
  3. echo %line1%&echo %line2%
  4. :loop
  5. set /a lines+=1
  6. set erl=0
  7. for /f "skip=%lines%" %%a in (1.txt) do echo %%a&set /a erl+=1&goto loop_1
  8. :loop_1
  9. for /f "skip=%lines%" %%a in (2.txt) do echo %%a&goto loop
  10. if %erl%==0 (pause) else (goto loop)
复制代码

作者: defanive    时间: 2009-5-1 00:33     标题: 稍加更改

改了一下,前两行的显示貌似要快点,实际上与LS的代码都是一样快的(测试耗时:0.05秒)
  1. @echo off
  2. for /f %%a in (1.txt) do echo %%a&for /f %%b in (2.txt) do echo %%b&goto loop
  3. :loop
  4. set /a lines+=1
  5. set erl=0
  6. for /f "skip=%lines%" %%a in (1.txt) do echo %%a&set /a erl+=1&goto loop_1
  7. :loop_1
  8. for /f "skip=%lines%" %%a in (2.txt) do echo %%a&goto loop
  9. if %erl%==0 (pause) else (goto loop)
复制代码

作者: everest79    时间: 2009-5-1 00:44

原帖由 netbenton 于 2009-4-30 23:34 发表
是我搞错了,呵呵,没注到前面的是find,而不是findstr


君的方法,不知道这样是不是可以不限行数了呢:
find /v /n "" ?.txt |findstr "[ ]"|sort


应该不行,把不同位数的行数分捡开来是为了让sort来正确排序,否则会排成
1
10
11
2
20
21
3
....
这样
超过一百行要再加一句
  1. for /f "tokens=1* delims=[]" %%a in ('find /v /n "" ?.txt^|findstr /b "\[[0-9][0-9][0-9]\]"^|sort') do echo.%%b >>out.txt
复制代码

作者: qzwqzw    时间: 2010-1-4 17:44

再把老古董翻出来晒晒吧 :-P

第一眼看到这个题目
下意识就想到用find+sort
后来发现everest79 已经有了类似的解题思路了
东施效颦的事我可不想做
本来就想放弃的

再后来我突然又想起了阔别很久的文物程序fc
也把它翻出来晒晒后
证实思路是可行的
  1. @(for /f "tokens=1* delims=: " %%a in ('fc /lb10000 /n ?.txt %SystemDrive%\io.sys^|find ": "^|sort') do @echo.%%b)>out2.txt
复制代码
比everest79的代码简单一些倒是其次
最关键的是这是一个新的创意

本以为万事大吉
可是再再后来又注意到netbenton与everest79 的对话
发现无论如何也不明白everest79的代码
怎么就避免了netbenton所说的错行问题

因为sort是按文本顺序排序的
而且无法指定排序起始点
不能指定排序停止点
那么文本的内容必然会影响到文本的顺序
试验证实也确实如此

关键糟糕的是
我的代码也存在同样的问题
而且它也把两个文本行首的空格给过滤掉了
于是只好再翻翻doshelp
终于找到解法

用findstr给文本行加个文件名前缀
让sort可以按照我们的规矩“正常排序”
而文本行首的空格也给保留了

虽然使用了临时文件
而且也多了两句代码
但这是没办法的事情
何况效率也没大影响
索性就这样结束了吧
  1. @echo off
  2. for %%f in (1.txt 2.txt) do findstr $ %%f? > %temp%\~%%~nf.%~n0
  3. (for /f "tokens=2* delims=:" %%a in ('fc /lb10000 /n %temp%\~*.%~n0 %SystemDrive%\io.sys^|find ": "^|sort') do echo.%%b)>out3.txt
  4. del %temp%\~*.%~n0
复制代码

作者: ccr438758900    时间: 2010-1-13 00:21

  1. @echo off
  2. setlocal enabledelayedexpansion
  3. set "xp=goto :eof"
  4. for /f "delims=" %%i in (1.txt) do (set "me=%%j"&echo %%i&call :a)
  5. set xp=&set vs=pause
  6. goto a
  7. :a
  8. for /f "%a% delims=" %%j in (2.txt) do (echo %%j&set /a b+=1&set a=skip=!b!
  9. %xp%)
  10. %vs%
复制代码

[ 本帖最后由 ccr438758900 于 2010-1-13 00:22 编辑 ]
作者: a590687    时间: 2010-1-27 11:41

  1. @echo off&setlocal enabledelayedexpansion
  2. ::先获取行数并把 行数较大的文本设为和t1另一个为t2
  3. for %%a in ('sed "$=" a.txt') do (
  4. for %%b in ('sed "$=" b.txt') do (
  5. if %%a gtr %%b (
  6. set "t1=a.txt"
  7. set "t2=b.txt"
  8. ) else (
  9. set "t1=b.txt"
  10. set "t2=a.txt"
  11. )
  12. )
  13. )
  14. ::交叉输出t1和t2
  15. for /f "delims=" %%i in (!t1!) do (
  16. set /a n+=1
  17. echo %%i
  18. for /f "tokens=1,* delims=:" %%j in ('findstr /n ".*" !t2!') do (
  19. if %%j equ !n! echo %%k
  20. )
  21. )
  22. pause
复制代码

作者: vincentzhou    时间: 2011-1-2 15:57

  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 编辑 ]
作者: 白手真三    时间: 2011-1-2 16:07

高手啊弄多语句
作者: powerbat    时间: 2011-1-2 17:32     标题: 回复 41楼 的帖子

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

这个评论果然中肯!这样的命令和用法也能联想到一起,还能奏奇效,不服不行!
作者: caruko    时间: 2011-1-2 23:42

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

CMD要是能够实现内存映射,多进程使用公共变量就好了。。
作者: CrLf    时间: 2011-2-22 18:14

这是刚想到的,没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 编辑 ]
作者: CrLf    时间: 2011-4-2 12:47

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
复制代码

作者: qzwqzw    时间: 2011-4-11 18:11

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

另外
find /n /v "" 2.txt|more>tmp2 +2
可以改用
find /n /v "" <2.txt>tmp2
更好些
作者: CrLf    时间: 2011-4-11 20:05

好办法,避开了多余的显示,省一个more。
其实如果文件数是2的倍数,还是可以这样用的,不过效率就难说了
作者: qzwqzw    时间: 2011-4-11 20:24

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

另外这只是原型代码
真正实用还要考虑一些细节
比如文本的末行没有\r\n
作者: CrLf    时间: 2011-7-18 20:23

本帖最后由 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. ::由于可以有两个不同的输入来源并存,所以双文本合并就成为轻而易举的事了
复制代码

作者: 尘丶    时间: 2015-8-31 19:37

  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
复制代码

作者: ai20110304    时间: 2018-9-5 23:07

  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
复制代码

作者: qixiaobin0715    时间: 2021-2-20 10:12

  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
复制代码

作者: netdzb    时间: 2021-2-20 13:01

回复 1# batman


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




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