[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]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楼更新后的需求)

先谢谢各位老大了。

本帖最后由 523066680 于 2018-1-30 10:06 编辑

字幕?

Perl

2018-01-30 更新

      use File::Slurp;
      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 @arr = read_file( $en );
          my @brr = read_file( $cn );
          my @mix;
          grep
          {
              $arr[$_] =~s/\r?\n//;
              $arr[$_] .= " ". $brr[$_]
          }
          ( 0 .. $#arr );

          @mix = grep { ( /^\d+\s+\d+$/ or /\d+:\d+:\d+/ or /^\s+$/ ) ? 0 : 1 } @arr;
          write_file( $merge, @mix );
          print "$merge\n";
      }

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

TOP

PowerShell
保存为ps1扩展名文件,右键单击脚本,以powershell运行
未对powershell进行过设置的,可以管理员身份运行CMD,复制此命令到命令提示符 powershell -c "set-executionpolicy unrestricted" 以解除脚本限制
WIN10以下系统如出错,可能需要去微软官网下载补丁升级powershell

根据5楼的要求,更新了下代码
  1. $SD_eng=Get-ChildItem -Path "C:\Users\CH6\Desktop\TEDTXTUNICODE\eng1246"
  2. $SD_chs=Get-ChildItem -Path "C:\Users\CH6\Desktop\TEDTXTUNICODE\chs1203"
  3. $OD_merge="C:\Users\CH6\Desktop\TEDTXTUNICODE\merge"
  4. foreach($file_eng in $SD_eng){
  5.      $content=$content_eng=$content_chs=$null;
  6.      foreach($file_chs in $SD_chs){
  7.         if($file_eng.name -eq $file_chs.name){
  8.             $content_eng=Get-Content -Path $file_eng.FullName;
  9.             $content_chs=Get-Content -Path $file_chs.FullName;
  10.             break;
  11.         }#if
  12.       }#for2  
  13.       if(($content_eng.Count-$content_chs.Count) -ge 0){$count=$content_eng.Count}else{$count=$content_chs.Count;}
  14.      for($i=2;$i -le $count;$i+=4){
  15.         if ($content_eng[$i-2] -ne $content_chs[$i-2]){-join('文件',$file_eng.name,"`t在第",(($i-2)/4+1),'行号不对应');}
  16.         if ($content_eng[$i-1] -ne $content_chs[$i-1]){-join('文件',$file_eng.name,"`t在第",(($i-2)/4+1),'时间轴不对应');}
  17.         if(!($content_eng[$i])){-join('文件',$file_eng.name,"`t在第",(($i-2)/4+1),'无英文字幕');}
  18.         if(!($content_chs[$i])){-join('文件',$file_eng.name,"`t在第",(($i-2)/4+1),'无中文字幕');}
  19.         $content+=-join($content_eng[$i]," ",$content_chs[$i]+"`r`n");
  20.       }
  21.       if($content){$OF_name=$OD_merge+'\'+$file_eng.name;$content|Out-File -FilePath $OF_name;}
  22. }
  23. pause;
复制代码

TOP

本帖最后由 allenyzq147 于 2018-1-29 23:36 编辑

回复 2# 523066680


    感谢您的回答。

    大神好眼力啊。的确是字幕文件,我是用来做语料库的。

    第一次运行Perl脚本
    我安装了StrawberryPerl,运行脚本后,只生成了一个TEDTXTUNICODE文件夹,这个文件夹下面有一个空的merge文件夹。
    是不是我装的软件不对.

TOP

回复 3# yhcfsr

感谢你了,这位哥哥。文件已成功合并。不然一千多份文件,一行一行,非要了我的小命。

可是,由于我提问之前考虑不够周全,出现了新的问题:行号、时间轴、还有空行,这3行都是不需要的。
只要留一行一行的英文和中文的文字就可以了。

能不能麻烦哥哥你,
再给写个脚本把merge文件夹里所有的文本里的 行号、时间轴、空行 都给删除
或者把刚才的脚本给改一下,我重新合并也可以。

再次感谢!

刚才合并后的每一个新文本,都是下面这样的格式,随机打开了一个,随机复制了几行:

11 11
00:00:39,000 --> 00:00:41,000 00:00:39,000 --> 00:00:41,000
We didn't know 我们不知道

12 12
00:00:41,000 --> 00:00:43,000 00:00:41,000 --> 00:00:43,000
if he had perished yet 是否他还活着

13 13
00:00:43,000 --> 00:00:46,000 00:00:43,000 --> 00:00:46,000
until 36 hours later. 直到事发36小时之后。

最终结果需要是下面的样子:

We didn't know 我们不知道
if he had perished yet 是否他还活着
until 36 hours later. 直到事发36小时之后。

TOP

本帖最后由 523066680 于 2018-1-30 09:01 编辑

回复 4# allenyzq147


    你需要把

my $path_eng = '.\TEDTXTUNICODE\eng1246';
my $path_chs = '.\TEDTXTUNICODE\chs1203';
my $path_merge = '.\TEDTXTUNICODE\merge';

这三行的路径改成你自己的,以及按你更新后的需求,最好是打包几个eng和chn的文件样本发上来,或者完整的打包发到网盘。
不然别人帮你解决问题,还得自己模拟文件环境,自己测试自己校验,最后发现需求改了?

TOP

  1. @echo off
  2. Setlocal enabledelayedexpansion
  3. set "txtPath1=C:\Users\CH6\Desktop\TEDTXTUNICODE\eng1246"
  4. set "txtPath2=C:\Users\CH6\Desktop\TEDTXTUNICODE\chs1203"
  5. for /f "delims=" %%i in ('dir /b/l/aa %txtPath1%\*.txt') do (
  6. for /f "delims=" %%a in ('dir /b/l/aa %txtPath2%\*.txt') do (
  7. if "%%i"=="%%a" (
  8. echo,%%i %%a 组合后。
  9. for /f "usebackq tokens=1,* delims=:" %%t in (`findstr /n "." "%txtPath1%\%%i"`) do (
  10. for /f "usebackq tokens=1,* delims=:" %%c in (`findstr /n "." "%txtPath2%\%%a"`) do (
  11. if "%%c"=="%%t" echo,%%u %%d
  12. )
  13. )
  14. )
  15. )
  16. )
  17. pause
复制代码
踏实一些点.不要着急.你想要的时间都会给你.2

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

更新:

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

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

TOP

回复 6# 523066680


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

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

TOP

回复 10# yhcfsr


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

    再次表示感谢!

TOP

回复 8# 慕夜蓝化


    感谢您的回复!

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

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

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

TOP

回复 13# allenyzq147


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

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

返回列表