Board logo

标题: [文本处理] [已解决]大文本,批处理或其他工具如何比较每行不同的字,并导出来。 [打印本页]

作者: 每天几分    时间: 2023-3-22 09:48     标题: [已解决]大文本,批处理或其他工具如何比较每行不同的字,并导出来。

如:

1.txt
保正
不之道
部可一世
浪字回头近不换

2.txt
保证
不知道
不可一世
浪子回头金不换

1、2txt中,每一行都有不同的字,每行文字数量都是一一对应的。这2个文本是经过了Beyond Compare比对的,我导出了差异的部分分为1、2两个文本。

批处理如何把相同的字删掉,留下不同的字。

实现:

3.txt
正→证
之→知
部→不
字近→子金

   
https://ibb.co/K5HTY4M

就是把标红的字提取出来,但Beyond Compare好像没这个功能
作者: 77七    时间: 2023-3-22 11:01

  1. @echo off
  2. set /a n=0,len=每行字数不超过=30
  3. setlocal enabledelayedexpansion
  4. for /f "delims=" %%a in ('type "1.txt"') do (
  5. set str1=%%a
  6. set /a n+=1,m=0
  7. for /f "delims=" %%b in ('type "2.txt"') do (
  8. set /a m+=1
  9. if !n! equ !m! (
  10. set str2=%%b
  11. set part1=
  12. set part2=
  13. for /l %%l in (0,1,%len%) do (
  14. if "!str1:~%%l,1!" neq "!str2:~%%l,1!" (
  15. set "part1=!part1!!str1:~%%l,1!"
  16. set "part2=!part2!!str2:~%%l,1!"
  17. )
  18. )
  19. >>3.txt echo !part1!→!part2!
  20. )
  21. )
  22. )
  23. endlocal
  24. pause
复制代码

作者: Batcher    时间: 2023-3-22 11:12

回复 1# 每天几分


真实的文本大概有多少行?
真实的文本大部分行是相同的还是不同的?
作者: 每天几分    时间: 2023-3-22 11:19

回复 3# Batcher


    大概100万行,每行文字长度跟另一个文本同行的长度都是相同的。
作者: 每天几分    时间: 2023-3-22 11:37

回复 2# 77七


    这个行数少是可行的,100万行跑了20分钟了,还没出结果。
作者: Batcher    时间: 2023-3-22 12:02

回复 4# 每天几分


我换个问法:
这个100万行里面,每一行都有不同的字?还是绝大部分行在两个文件里面是相同的,只有少数行有不同的字?
作者: 每天几分    时间: 2023-3-22 12:09

回复 6# Batcher


    每一行都有不同的字。这2个文本是经过了Beyond Compare比对的,我导出了差异的部分分为2个文本。
作者: 每天几分    时间: 2023-3-22 12:23

本帖最后由 每天几分 于 2023-3-22 12:25 编辑

回复 6# Batcher


   
https://ibb.co/K5HTY4M

就是把标红的字提取出来,但Beyond Compare好像没这个功能
作者: 77七    时间: 2023-3-22 12:28

回复 5# 每天几分


   可以在顶楼标准一下,”超大文本,100万行”。请会使用第三方文本处理工具的老师帮忙。
作者: terse    时间: 2023-3-22 14:40

BAT+js 应该会好点,
  1. @if(0)==(0) echo off
  2. rem ansi编码保存文件
  3. cscript.exe //NoLogo //E:JScript "%~f0" 1.txt 2.txt>3.txt
  4. pause&goto:eof
  5. @end
  6. function getText(file){
  7.        var fso, fi, arr;
  8.        fso = new ActiveXObject("Scripting.FileSystemObject");
  9.        fi = fso.OpenTextFile(file);
  10.        arr = fi.ReadAll().split(/[\n|\r\n]{1,}/);
  11.        fi.Close();
  12.        return arr;
  13. }
  14. var arr,brr, ar,br;
  15. arr = getText(WSH.Arguments(0));
  16. brr = getText(WSH.Arguments(1));
  17. var len=arr.length;
  18. for (var i=0; i<len; i++) {
  19.       ar = arr[i].split('');
  20.       br= brr[i].split('');
  21.       var length = ar.length;
  22.       var a='',b='';
  23.       for (var j=0; j<length; j++) {
  24.              if (ar[j] != br[j] ){
  25.                  a += ar[j];
  26.                  b +=br[j];
  27.              }
  28.       }
  29.       if (a) {WSH.Echo(a + " → " + b)};
  30. }
复制代码

作者: 每天几分    时间: 2023-3-22 15:08

回复 10# terse


    (20, 7) Microsoft JScript 运行时错误: 'brr[...]' 为 null 或不是对象
这个速度是可以,但是出现了以上提示,生成的结果前面部分还能对应上,后面就不对应了。
作者: terse    时间: 2023-3-22 15:43

回复 11# 每天几分
前面能处理的话 查一下文本格式呢 按你说的情况每行字数相同,行数相同 所以代码没做其他判断
作者: 每天几分    时间: 2023-3-22 16:09

回复 12# terse


    多谢,解决了,是文本中的空行造成的。速度很快,不到1分钟。
作者: newswan    时间: 2023-3-22 16:16

提供一个思路:
bc 比较结果导出,如果能带颜色的话,就简单了
作者: qixiaobin0715    时间: 2023-3-26 09:56

本帖最后由 qixiaobin0715 于 2023-3-26 10:41 编辑

纯P。手头没有测试样本,不知这样效率如何,100万行的话,我想处理时间应当不会超过一刻钟。最多每行字数不超过10个(如果字数不满足,可修改代码第6行for /l的终值):
  1. @echo off
  2. (for /f "delims=" %%i in (1.txt) do (
  3.     setlocal enabledelayedexpansion
  4.     set str1=%%i
  5.     set /p str2=
  6.     for /l %%a in (0,1,9) do (
  7.         if "!str1:~%%a,1!" neq "!str2:~%%a,1!" (
  8.             set str3=!str3!!str1:~%%a,1!
  9.             set str4=!str4!!str2:~%%a,1!
  10.         )
  11.     )
  12.     if defined str3 echo,!str3! !str4!
  13.     endlocal
  14. ))<2.txt>3.txt
  15. pause
复制代码

作者: CrLf    时间: 2023-3-26 16:48

感觉可以考虑用BeyongCompare导出成html报告,再直接提取红字部分,这样会比批处理做比对要快很多
作者: hfxiang    时间: 2023-3-26 22:43

回复 1# 每天几分

  1. BEGIN {
  2. FS = ""
  3. F1 = gensub(/\\/, "/", "g", F1)
  4. F2 = gensub(/\\/, "/", "g", F2)
  5. F3 = gensub(/\\/, "/", "g", F3)
  6. while ((getline < F1) > 0) {
  7. n1 = split($0, a, FS)
  8. (getline < F2)
  9. n2 = split($0, b, FS)
  10. if (n1 == n2) {
  11. c = d = o_id = ""
  12. for (i = 1; i <= n1; ++i) {
  13. if (a[i] != b[i]) {
  14. c = c a[i]
  15. d = d b[i]
  16. o_id = 1
  17. }
  18. }
  19. if (o_id) {
  20. print(c "\241\372" d) > F3
  21. }
  22. }
  23. }
  24. }
复制代码
以ANSI编码格式保存为"D:\桌面\python\新建文件夹\a.awk"。
确保"D:\桌面\python\新建文件夹\1.txt"及"D:\桌面\python\新建文件夹\2.txt"的文件结构完全一致,并且已保存为ANSI编码格式。
下载gawk ( http://bcn.bathome.net/tool/4.1.0/gawk.exe ),放置为"D:\桌面\python\新建文件夹\gawk.exe",执行:
  1. "D:\桌面\python\新建文件夹\gawk.exe" -vF1="D:\\桌面\\python\\新建文件夹\\1.txt" -vF2="D:\\桌面\\python\\新建文件夹\\2.txt" -vF3="D:\\桌面\\python\\新建文件夹\\3.txt" -f"D:\桌面\python\新建文件夹\a.awk"
复制代码

作者: terse    时间: 2023-3-27 18:15

gawk的话 这样也可以
  1. gawk -v file="2.txt" -F "" "{for(i=1;i<=NF;i++)a[i]=$i}{getline<file;s=null;for(i=NF;i>0;i--)if(a[i]!=$i ){s=s==null?a[i]\"→\"$i:a[i] s $i};if(s)print(s)}" 1.txt >3.txt
复制代码





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