[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖
我的,有点晚:
  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
复制代码
1

评分人数

(*^_^*)

TOP

最后给出本人的第三个方案,生成临时文件且通用性不很强,
解题思路和上面的完思路不同:
  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
复制代码
***共同提高***

TOP

jm厉害,考虑这么全面。
心绪平和,眼藏静谧。

TOP

  把两个文本的相同行交叉合并,需要考虑以下两种情况:
  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行,并且不能保证某个文件的行内容总是排在两行中的第一行或第二行。
  注:以上代码都没有考虑特殊字符。
尺有所短寸有所长,学好批处理没商量;
考虑问题复杂化,解决问题简洁化。

心在天山,身老沧州。

TOP

@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
要是就本题的几行上面的还行

TOP

再次提示:
第三种方法可就本题而言来解(不考虑行数太多的情况)
***共同提高***

TOP

为了减少不必要的调用,修改如下。
  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
复制代码
心绪平和,眼藏静谧。

TOP

既然这种最高效的方法也出来了(只可惜是版主级做出来的),下面就贴出本人的第二种方法:
  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
复制代码
***共同提高***

TOP

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

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

我想在这里应该不有去考虑极端情况,比如特殊字符处理什么的。
***共同提高***

TOP

@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 编辑 ]
1

评分人数

    • batman: 这样的代码效率是最高的。PB + 10
心绪平和,眼藏静谧。

TOP

原帖由 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 编辑 ]
***共同提高***

TOP

想得头都要破了

  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 编辑 ]
2

评分人数

TOP

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

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

TOP

的确如此 思维定向了。
心绪平和,眼藏静谧。

TOP

也可以根本不必要判断文本的行数。
技术问题请到论坛发帖求助!

TOP

返回列表