Board logo

标题: [文本处理] [求助]批处理只要有相同内容,就保留那一行 [打印本页]

作者: jrx401    时间: 2020-2-6 09:40     标题: [求助]批处理只要有相同内容,就保留那一行

详细如下;
A.txt内容;
11111
CCCCC

B.txt内容;
aa bb D1111
1ac bhy 11111
15c b6y 11112
1ac b8y A1111
2ac 9bhy 11111
75c b6y CCCCC
15c c6y 11111

处理后C.txt【只保留A里有,B内容里 第3列一致的 行】;
1ac bhy 11111
2ac 9bhy 11111
75c b6y CCCCC
15c c6y 11111

如下code是可以处理,但是A.txt, B.txt里面有1万行时,就耗时20分钟。
可否有快速处理的方法呢?

使用的code;
  1. @echo off
  2. setlocal enabledelayedexpansion
  3. for /f "tokens=1,2,3 delims= " %%c in (B.txt) do (
  4.     findstr /c:"%%h" A.txt>nul&&echo %%c %%d %%e
  5.    ))>C.txt
  6. endlocal
复制代码
还请高手指点。
感谢
作者: flashercs    时间: 2020-2-6 11:39

  1. @echo off
  2. pushd "%~dp0"
  3. set "fileA=A.txt"
  4. set "fileB=B.txt"
  5. set "fileC=C.txt"
  6. findstr /elg:"%fileA%" "%fileB%">"%fileC%"
  7. popd
  8. pause
  9. exit /b
复制代码

作者: flashercs    时间: 2020-2-6 12:39

精确查找
  1. @echo off
  2. REM 在fileB中查找行which-第三列包含于fileA中-保存到fileC
  3. if not "%~1"=="" goto print
  4. pushd "%~dp0"
  5. set fileA="A.txt"
  6. set fileB="B.txt"
  7. set fileC="C.txt"
  8. setlocal EnableDelayedExpansion
  9. for /f "usebackq tokens=1 delims=" %%A in (%fileB%) do (
  10.   set /a "n+=1"
  11.   set "#!n!=%%A"
  12. )
  13. >%fileC% (
  14.   for /f "tokens=1 delims=:" %%A in ('"%0 %fileB%|findstr /nlxg:%fileA%"') do (
  15.     echo !#%%A!
  16.   )
  17. )
  18. endlocal
  19. popd
  20. pause
  21. exit /b
  22. :print
  23. for /f "usebackq tokens=3" %%a in ("%~1") do (
  24.   echo %%a
  25. )
  26. exit /b
复制代码

作者: jrx401    时间: 2020-2-6 13:08

回复 2# flashercs


    感谢大侠。
    测试结果,C.txt 是空的。
   
作者: jrx401    时间: 2020-2-6 13:11

回复 3# flashercs


        感谢大侠。
    测试结果,C.txt 也是空的。
作者: Gin_Q    时间: 2020-2-6 13:41

如果A里面有B里面没有就不用写入C里面了吧!
作者: Gin_Q    时间: 2020-2-6 13:44

B里面的格式是否都是空格分割的?是否只需要匹配第三列的内容?
作者: jrx401    时间: 2020-2-6 13:53

回复 7# Gin_Q


    B里面的格式是否都是空格分割的?
     ->有些是间隔符
    是否只需要匹配第三列的内容?
     ->是的
作者: jrx401    时间: 2020-2-6 13:54

如果A里面有B里面没有就不用写入C里面了吧!
Gin_Q 发表于 2020-2-6 13:41



    如果A里面有B里面没有的行 就不用写入C里面。
作者: flashercs    时间: 2020-2-6 14:25

回复 5# jrx401

那你下载试试
作者: went    时间: 2020-2-6 16:06

本帖最后由 went 于 2020-2-6 16:08 编辑
  1. @echo off
  2. set "pattern="
  3. for /f "delims=" %%i in (A.txt) do call set "pattern=%%pattern%%.*%%i$ "
  4. type "B.txt" | findstr "%pattern%" > "C.txt"
  5. pause
复制代码
确保你的第三列是最后一列
作者: Gin_Q    时间: 2020-2-6 16:47

C语言写的,以下是源代码:
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. #define MAX 2048
  5. void ch(char *);
  6. int star(char *b,FILE *a);
  7. int main(int argc,char *argv[3])
  8. {
  9. /*设置路径
  10. char *Path_a="C:\\Users\\Cool_Breeze\\Desktop\\gin\\test\\a.txt";
  11. char *Path_b="C:\\Users\\Cool_Breeze\\Desktop\\gin\\test\\b.txt";
  12. char *Path_c="C:\\Users\\Cool_Breeze\\Desktop\\gin\\test\\c.txt";
  13. */
  14. //打开文件
  15. FILE *fp_a,*fp_b,*fp_c;
  16. char a[MAX],b[MAX],c[MAX];
  17. if ((fp_a=fopen(*(argv+1),"r"))==NULL)
  18. {
  19. printf("%s 打开失败!",*(argv+1));
  20. return 0;
  21. }
  22. if ((fp_b=fopen(*(argv+2),"r"))==NULL)
  23. {
  24. printf("%s 打开失败!",*(argv+2));
  25. return 0;
  26. }
  27. if ((fp_c=fopen(*(argv+3),"w"))==NULL)
  28. {
  29. printf("%s 打开失败!",*(argv+3));
  30. return 0;
  31. }
  32. while(fgets(b,MAX,fp_b)!=NULL)
  33. {
  34. if (star(b,fp_a)==1)                //写入
  35. {
  36. fprintf(fp_c,"%s",b);
  37. }
  38. }
  39. fclose(fp_a);
  40. fclose(fp_b);
  41. fclose(fp_c);
  42. return 0;
  43. }
  44. int star(char *b,FILE *a)
  45. {
  46. char b_s[MAX];                            //储存第三列字符串
  47. char *c=b_s;
  48. int d=0,n=0;
  49. while (*(b+n++) != '\0')
  50. {
  51. if (*(b+n) == ' ')
  52. {
  53. d++;
  54. if (d==2)                         //出现第二个分隔符后拷贝第三列字符串
  55. {
  56. strncpy(c,b+n+1,MAX);         //拷贝
  57. ch(c);
  58. goto A;
  59. }
  60. }
  61. }
  62. A:                                         
  63. char temp[MAX]="0";
  64. fseek(a,0,SEEK_SET);                      //恢复文件指针
  65. while(fgets(temp,MAX,a)!=NULL)
  66. {
  67. ch(temp);
  68. if (strncmp(temp,c,MAX)==0)           //比较字符串
  69. {
  70. return 1;                         //一样返回1
  71. }
  72. }
  73. return 0;                                 //不一样返回0
  74. }
  75. void ch(char *old)
  76. {
  77. char sta;
  78. do
  79. {
  80. sta=*(old++);
  81. if (sta == '\n' || sta == '\r')
  82. {
  83. old[strlen(old)-1]='\0';          //去掉换行符
  84. }
  85. }while(sta);
  86. }
复制代码

作者: Gin_Q    时间: 2020-2-6 16:52

你加入微信群没有?
作者: Batcher    时间: 2020-2-7 10:14

回复 1# jrx401


推荐试试 gawk 这个命令行工具
  1. gawk "NR==FNR{a[$1]=$1}NR>FNR{if($3 in a)print}" "A.txt" "B.txt" > "C.txt"
复制代码
http://bcn.bathome.net/s/tool/index.html?key=gawk
作者: Gin_Q    时间: 2020-2-7 12:11

行不行给个话呗!我想看看处理速度怎么样?
作者: jrx401    时间: 2020-2-7 17:50

确保你的第三列是最后一列
went 发表于 2020-2-6 16:06



    感谢大虾,
    高手!!!缩短到 5s 以内 。
作者: jrx401    时间: 2020-2-7 17:51

回复 11# went


    高手!!!
    缩短到5s以内
作者: jrx401    时间: 2020-2-7 17:52

回复 10# flashercs


    可以了,敢虾高手。
作者: jrx401    时间: 2020-2-7 17:58

回复 12# Gin_Q


    敢虾大虾协助。
    但是 c.txt结果 里面空值。
作者: Gin_Q    时间: 2020-2-8 09:29

回复 19# jrx401


    把你的文本发出来看看吧?




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