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

[文本处理] BAT脚本如何批量按行合并2个不同文件夹下的同名txt文件

按版主建议,把示例文档和5楼更新后的需求一并上传。

小妹是新手,弄了好几天了,始终搞不定。只有求大神哥哥们帮帮忙了。

我有2个文件夹,下面有大量同名txt文件:
文件夹eng1246的路径 C:\Users\CH6\Desktop\TEDTXTUNICODE\eng1246
文件夹chs1203的路径 C:\Users\CH6\Desktop\TEDTXTUNICODE\chs1203

文件夹eng1246下有1246个txt文件,文件名无规律
文件夹chs1203下有1203个txt文件,基本上每一个在文件夹eng1246下都有对应的同名文件(个别也许没有)

文件夹eng1246里有一些多余文件,在文件夹chs1203下没有对应文件。

现需要把在2个文件夹下的同名文件两两按行合并,形成新的txt文件,仍用原名,输出到一个新的文件夹内(新文件夹路径 C:\Users\CH6\Desktop\TEDTXTUNICODE\merge)。

每一个新文本XXX的格式如下:

文件夹eng1246下文本XXX的第一行  文件夹chs1203下文本XXX的第一行(中间用1个空格隔开)
文件夹eng1246下文本XXX的第二行  文件夹chs1203下文本XXX的第二行(中间用1个空格隔开)
文件夹eng1246下文本XXX的第三行  文件夹chs1203下文本XXX的第三行(中间用1个空格隔开)
。。。
。。。
所有合并后的新文本里的 行号、时间轴、空行 都给删除(此为5楼更新后的需求)

先谢谢各位老大了。

本帖最后由 WHY 于 2018-2-2 22:24 编辑
  1. function MergeFiles($chsFile, $engFile){
  2.     $hash = @{}; $s1 = $s2 = '';
  3.     ForEach($strLine In (type $chsFile)){
  4.         If($s1 -like '[0-9][0-9]:*') { $hash[$s1] = $strLine; }
  5.         $s1 = $strLine;
  6.     }
  7.     ForEach($strLine In (type $engFile)){
  8.         If($s2 -like '[0-9][0-9]:*'){$strLine + ' ' + $hash[$s2];}
  9.         $s2 = $strLine;
  10.     }
  11. }
  12. $chsDir = 'C:\Users\CH6\Desktop\TEDTXTUNICODE\chs1203';
  13. $engDir = 'C:\Users\CH6\Desktop\TEDTXTUNICODE\eng1246';
  14. $mergeDir = 'C:\Users\CH6\Desktop\TEDTXTUNICODE\merge';
  15. If(!(Test-Path $mergeDir)){$null = md $mergeDir;}
  16. ForEach($eng In (dir ($engDir + '\*.txt'))){
  17.     $chsFile = $chsDir + '\' + $eng.Name;
  18.     If(Test-Path $chsFile){
  19.         $arr = MergeFiles $chsFile $eng.FullName;
  20.         Set-Content ($mergeDir + '\' + $eng.Name) $arr -Enc unicode;
  21.     }
  22. }
  23. [Console]::Write('Done');
  24. [Console]::ReadLine()
复制代码

TOP

回复 17# allenyzq147


    哈哈,你还是蛮可爱的。嗯,需要jdk8,你安装好之后。在桌面新建一个txt文档,将代码复制到文本中,并将文件名更改为BRDemo.java。保存完毕后,win7下shift鼠标右键->在此处打开命令窗口。输入 javac BRDemo.java 回车。 会生成一个class 文件。 然后,在命令窗口中继续输入 java BRDemo ,即可看到打印出的信息。如果在这个过程中有不明了的,可以加下我q,1451979729,也欢迎各位添加,共同交流。
踏实一些点.不要着急.你想要的时间都会给你.2

TOP

回复 18# 523066680


    感谢版主大神这么耐心的解释。

    再次感谢所有答题的哥哥们。

TOP

本帖最后由 523066680 于 2018-1-30 17:39 编辑

回复 16# allenyzq147

    上一段代码只对 utf8 gbk 之类(这类编码和 ASCII 码兼容)的编码起作用。现在的代码只对  utf16-le 编码起作用。
旧代码的问题以及原因:utf16-le 对 ASCII 范围的编码补0,扩充到两个字节,这样换行\r\n就不是 0d 0a, 而是 0d 00 0a 00,匹配换行的时候就会有差异。

TOP

回复 14# 慕夜蓝化


    作为一个处女座,我还是没忍住安装了JDK,配置了环境变量,测试了那段JAVA代码。

结果
:6:错误:类BRDemo是公共的,应在名为BRDemo.java的文件中声明......bla bla

TOP

回复 15# 523066680

   
    非常感谢版主大人。

    刚测试了你更新后的代码,非常顺利,便于我把一些时间线不匹配的字幕找出来。
   
    这段代码与前面代码区别在哪里?
    你上一段代码只对UTF-8编码的文本起作用吗?

TOP

回复 11# allenyzq147

    哦,原来是 utf16-le 的编码。代码更新在附件,附输出结果(发现Adam Grosser的一些时间段是没有中文翻译的,如果按行合并,就会错乱。)
  1. Processing .\merge\A TED speakers worst nightmare.txt
  2. Processing .\merge\Adam Grosser - A mobile fridge for vaccines.txt
  3.   missing 00:00:28 at .\chs1203\Adam Grosser - A mobile fridge for vaccines.txt
  4.   missing 00:00:29 at .\chs1203\Adam Grosser - A mobile fridge for vaccines.txt
  5.   missing 00:00:31 at .\chs1203\Adam Grosser - A mobile fridge for vaccines.txt
  6.   missing 00:00:33 at .\chs1203\Adam Grosser - A mobile fridge for vaccines.txt
  7.   missing 00:00:37 at .\chs1203\Adam Grosser - A mobile fridge for vaccines.txt
  8.   ...
  9. Processing .\merge\Ahn Trio - A modern take on piano violin cello.txt
  10. Done
复制代码
我现在的处理方式是按时间段匹配,如果没有对应翻译就不输出。

TOP

回复 13# allenyzq147


    嗯,非成品,你需要加个括号以及重定向符,导入到指定的文件夹中就可以。
踏实一些点.不要着急.你想要的时间都会给你.2

TOP

回复 8# 慕夜蓝化


    感谢您的回复!

我按您第一回复的批处理脚本运行,有窗口显示在处理文本,但近半小时依然没有处理完,不得以暂停、关闭了。merge文件夹里没有得到任何合并后的文本。

第二次更新是java脚本吗,可我并不知道怎么运行。

虽然没成功,依然感谢您的热心。

TOP

回复 10# yhcfsr


    已经按更新后的脚本成功合并,并删除不需要的行。
    给你一个大大的

    再次表示感谢!

TOP

回复 6# 523066680


    感谢您的耐心,我已经把示例文档和更新后的需求都上传到一楼的附件里了。

更新后的perl脚本我测试了,雷神字幕的确正常合并,但我的字幕合并就是不成功。
按你第一次更新的脚本测试,merge文件夹里出现了合并后的文本,但打开全是乱码。
按你第二次更新的脚本测试,merge文件夹里也出现了合并后的文本,但全是空文本。

TOP

回复 5# allenyzq147
更新后的代码还放在二楼

TOP

更新:

1. chdir 路径 or 题主路径,这样不改代码就可以在我的目录和题主的环境上运行
  1. chdir '.\TEDTXTUNICODE' or
  2. chdir 'C:\Users\CH6\Desktop\TEDTXTUNICODE' or quit( $! );
复制代码
2. 增加时间轴匹配,时间对应才合并,如果没有匹配到时间会提示 missing $time at $filename

      =info
          523066680@163.com
          匹配时间轴,改善输出提示
      =cut

      use Encode;
      use File::Basename;
      use Term::ReadKey;
      STDOUT->autoflush(1);

      chdir '.\TEDTXTUNICODE' or
      chdir 'C:\Users\CH6\Desktop\TEDTXTUNICODE' or quit( $! );
      my $path_eng = '.\eng1246';
      my $path_chs = '.\chs1203';
      my $path_merge = '.\merge';

      mkdir $path_merge unless -e $path_merge;

      my ($en, $cn, $merge);
      for my $cn ( glob "$path_chs\\*.txt" )
      {
          $en = "$path_eng\\". basename($cn);
          $merge = "$path_merge\\". basename($cn);
          merge( $en, $cn, $merge ) if ( -e $en );
      }
      quit("Done");

      sub merge
      {
          my ( $en, $cn, $merge ) = @_;
          my ( %ha, %hb, $mix );
          print "Processing $merge\n";

          load( \%ha, $en );
          load( \%hb, $cn );
          $mix = "";
         
          for my $time ( sort keys %ha )
          {
              unless ( exists $hb{$time} )
              {
                  print "  missing $time at $cn\n";
                  next;
              }
              $mix .= $ha{$time} ." ". $hb{$time} ."\r\n";
          }

          open $fh, ">:raw", $merge;
          print $fh "\xff\xfe". encode('utf16-le', $mix);
          close $fh;
      }

      sub load
      {
          my ( $href, $file ) = @_;
          open my $fh, "<:encoding(utf16-le)", $file;
          my @arr = <$fh>;
          close $fh;
          for my $id ( 0 .. $#arr )
          {
              if ( $arr[$id] =~/(\d+:\d+:\d+).*\d+:\d+:\d+/ )
              {
                  $href->{$1} = $arr[$id+1];
                  $href->{$1} =~s/\r?\n//;
              }
          }
      }

      sub quit
      {
          print $_[0];
          ReadKey -1;
          exit;
      }


测试《雷神》字幕(手动去掉了一个时间轴)
Processing .\merge\Thor.txt
  missing 00:00:54 at .\chs1203\Thor.txt


.\merge\Thor.txt
Now, I know what you're thinking. 我知道你在想什么
"Oh, no! Thor's in a cage. How did this happen?" 不  托尔被关在笼子里了  怎么回事
Well, sometimes you have to get captured 有时  你得先被抓住
just to get a straight answer out of somebody. 才能从某人那里问出个所以然来
It's a long story, but basically, I'm a bit of a hero. 说来话长  但其实  我算是个英雄


分享个雷神字幕的示例包裹,含目录结构

TOP

  1. import java.io.BufferedReader;
  2. import java.io.File;
  3. import java.io.FileReader;
  4. import java.io.IOException;
  5. public class BRDemo {
  6. public static void main(String args[]) throws IOException{
  7. String txtPath1 = "C:\\Users\\CH6\\Desktop\\TEDTXTUNICODE\\eng1246";
  8. String txtPath2 = "C:\\Users\\CH6\\Desktop\\TEDTXTUNICODE\\chs1203";
  9. File f1 = new File(txtPath1);
  10. File f2 = new File(txtPath2);
  11. File fs1[] = null;
  12. if(f1.isDirectory()){
  13. fs1 = f1.listFiles((File ff,String name) -> {if(name.endsWith(".txt")){return true;}return false;});
  14. }
  15. File fs2[] = null;
  16. if(f2.isDirectory()){
  17. fs2 = f2.listFiles((File ff,String name) -> {if(name.endsWith(".txt")){return true;}return false;});
  18. }
  19. for(File fa : fs1){
  20. System.out.println("------------------------");
  21. System.out.println(fa.getPath());
  22. for(File fb : fs2){
  23. if(fa.getName().equals(fb.getName())){
  24. BufferedReader bra = new BufferedReader(new FileReader(fa));
  25. BufferedReader brb = new BufferedReader(new FileReader(fb));
  26. int na = 0;
  27. int nb = 0;
  28. String braStr;
  29. String brbStr;
  30. while(bra.ready()){
  31. na++;
  32. while(brb.ready()){
  33. nb++;
  34. if(nb == na){
  35. System.out.println(bra.readLine() + " " + brb.readLine());
  36. }
  37. nb = 0;
  38. }
  39. na = 0;
  40. }
  41. }
  42. }
  43. }
  44. }
  45. }
复制代码
踏实一些点.不要着急.你想要的时间都会给你.2

TOP

返回列表