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

[文本处理] 批处理合并两个大文件并删除重复行时为何无法运行?

在本论坛看到一段代码,是“合并两个文本到新文件并删除重复行”的,那个帖子的介绍如下:

批处理怎样合并两个文本到新文件并删除重复行?

两个文本文件 A.txt 和 B.txt,每个文件内容都只有一列,需合并两个
文件的内容到新文件C.TXT并删除重复行(重复内容只保留一个).示例如下:
A.txt的内容:        
111                  
222                    
333
444
555
666

B.txt的内容:
444
555
666

777
888
999
合并并删除重复行后的C.txt应该是:
111 ┐
222 │
333 ├────> A.Txt的内容
444 │┐┐
555 │┼┼──>A.TXT和B.TXT共有的重复内容(删除重复,作唯一化)
666 ┘┘│
777         ├──>B.TXT的内容
888         │
999 ──┘
即合并追加两文件列表内容,并删除重复行作唯一化处理(红色部分代表重复内容)

代码如下:
  1. @echo off
  2. set begin=%time%
  3. cd.>c.txt
  4. REM 方法一,测试花费时间在2毫秒左右
  5. REM 结果:
  6. REM 花费时间: 0 小时 0 分钟 0 秒 2 毫秒
  7. for /f "eol= delims=" %%a in (a.txt b.txt) do @if not defined %%a @(set "%%a=1" & echo %%a >> c.txt)
  8. REM 方法二,测试花费时间在55秒左右
  9. REM 结果:
  10. REM 完成,共花费时间: 0 小时 0 分钟 0 秒 54 毫秒
  11. REM for /f "delims=" %%i in (A.txt B.txt) do (
  12. REM find /i "%%i" C.txt||echo %%i>>C.txt
  13. REM )
  14. call :time0 %begin% %time% duration
  15. cls
  16. echo 完成,共花费时间: %duration%
  17. pause
  18. goto :eof
  19. :time0
  20. ::计算时间差(封装)
  21. @echo off&setlocal&set /a n=0&rem code 随风 @bbs.bathome.net
  22. for /f "tokens=1-8 delims=.: " %%a in ("%~1:%~2") do (
  23. set /a n+=10%%a%%100*360000+10%%b%%100*6000+10%%c%%100*100+10%%d%%100
  24. set /a n-=10%%e%%100*360000+10%%f%%100*6000+10%%g%%100*100+10%%h%%100)
  25. set /a s=n/360000,n=n%%360000,f=n/6000,n=n%%6000,m=n/100,n=n%%100
  26. set "ok=%s% 小时 %f% 分钟 %m% 秒 %n% 毫秒"
  27. endlocal&set %~3=%ok:-=%&goto :EOF
复制代码
当a.txt和b.txt为小文件时,批处理运行很好;但当两个文件为大文件(a、b文件均为27M)时,显示“命令语法不正确”!
请各位老大看看是什么问题?先谢谢了!!!

本帖最后由 CrLf 于 2011-7-24 22:38 编辑

排除指定行和双文本合并一直是批处理比较头痛的问题,要么不通用,要么效率低:
if defined 方法比较简单易行,但是有几个缺陷,一是随着定义的变量增加,效率将越来越低,二是内存中的变量存储有上限,碰到大文件就完蛋了,第三是最致命的,就是当文本内容中含有等号时,set 命令会产生错误的切分,导致误判删除其实并不相同的行。
而在遍历文本的 for 循环中嵌套使用 for 循环或者 find 来查找重复行的办法...不解释,效率低得不可忍受,除非要兼容内容超过8189字节的行,否则完全不考虑。
  1. @echo off&setlocal enabledelayedexpansion
  2. (for /f "tokens=1* delims=:" %%a in ('findstr /n .* 1.txt') do (
  3.     set t2=
  4.     set /p t2=
  5.     echo;%%b!t2!
  6. ))<2.txt>合并.txt
  7. ::不需兼容超过1024字节的行时,这是最快的方法
复制代码
如果高于 1024 字节,并且低于 8190 ,一般是用 if defined,但是若考虑到对 = 号的兼容性以及处理大文件的速度,还是用 fc+sort 命令进行合并、再用 sort 命令排序后再排除判断相邻两行是否相同(哦,无敌的 sort...)会更合适。

相关链接:
http://bbs.bathome.net/thread-1239-1-1.html
http://bbs.bathome.net/thread-4690-1-1.html
另外,如果文本1和文本2自身不包含重复行的话,建议用 findstr /v /l /g:1.txt 2.txt 来筛选,效率更高,不过缺陷是 findstr 匹配汉字时有可能出现 bug

TOP

试了一下,批处理窗口始终不关闭,产生了合并.txt,但只有0字节.

斑竹辛苦,谢谢!

TOP

返回列表