删除一些文本对的差异

时间:2012-06-21 10:08:52

标签: linux perl text

前几天我问过一个关于在两个文本文件中标记差异的问题,并且很快得到了解答。

现在我有一个相似的问题,但有点复杂。 我有两对文件,具有以下特点: pair1:(File1.txt,File2.txt) pair2:(File3.txt,File4.txt)

这些对中的每个文件之间存在逐行对应关系。假设File1.txt和File3.txt是一些英文单词,File2.txt和File4.txt分别是他们的阿拉伯语和法语翻译。另外,File1.txt和File3.txt非常相似(在某些情况下也是如此)。


    File1.txt       File2.txt
    EnWord1         ArTrans1
    EnWord2         ArTrans2
    EnWord3         ArTrans3
    Enword4         ArTrans4

    File3.txt       File4.txt
    EnWord1         FrTrans1
    EnWord3         FrTrans3
    Enword4         FrTrans4
    Enword5         FrTrans5

现在我要做的是比较这些对的英文边,找到两个文件中出现的常用词(EnWord1,EnWord3和EnWord4)并过滤掉它们对应的翻译。 简而言之,我可以说使用两种双语英语 - 阿拉伯语和英语法语词典,我正在尝试建立一个3种语言的英语 - 阿拉伯语 - 法语词典。 怎么可能?

我必须补充一点,因为有很多这样的对(字典存储在不同的文件中,每个文件都包含一部分单词,并且由于某些原因,不可能合并文件然后处理他们)代码的速度非常重要,我正在寻找一种快速的方法来实现这一点。

最后,请给我一些要点(甚至可能是完整的代码)在Perl中执行此操作。

最好的祝福, 哈基姆

4 个答案:

答案 0 :(得分:2)

将此视为提示,我尚未验证此

join <(paste file.1 file.2) <(paste file.3 file.4)

答案 1 :(得分:1)

我认为您要维护的订单遵循File1.txt。以下perl应该可以实现您的目标:

#!/usr/bin/perl

use strict;
use warnings;

my @pair1 = `paste -d ":" $ARGV[0] $ARGV[1]`;
my @pair2 = `paste -d ":" $ARGV[2] $ARGV[3]`;

my @pairs = (@pair1, @pair2);
my (%seen, @dups);

foreach (@pairs)
{
  my $word = (split ":", $_)[0];
  push @dups, $word if $seen{$word}++;
}

open (FILE0, ">", "NEW_File0.txt") or die;
open (FILE1, ">", "NEW_File1.txt") or die;
open (FILE2, ">", "NEW_File2.txt") or die;

foreach my $duplicate (@dups)
{
  print FILE0 "$duplicate\n";

  foreach (@pair1) { print FILE1 ((split ":", $_)[1]) if $_ =~ /^$duplicate:/; }
  foreach (@pair2) { print FILE2 ((split ":", $_)[1]) if $_ =~ /^$duplicate:/; }
}

close FILE0;
close FILE1;
close FILE2;

像这样跑:

./script.pl File1.txt File2.txt File3.txt File4.txt

grep "" NEW_File*结果:

NEW_File0.txt:EnWord1
NEW_File0.txt:EnWord3
NEW_File0.txt:EnWord4
NEW_File1.txt:ArTrans1
NEW_File1.txt:ArTrans3
NEW_File1.txt:ArTrans4
NEW_File2.txt:FrTrans1
NEW_File2.txt:FrTrans2
NEW_File2.txt:FrTrans3

可能不是最有效的做事方式,但至少应该给你一些起点。 HTH。

答案 2 :(得分:0)

这将是Perl的粗略代码。

%Dict1 = map { /^(.+),(.+)$/ } `paste file1.txt file2.txt -d,`;
%Dict2 = map { /^(.+),(.+)$/ } `paste file3.txt file4.txt -d,`;

print "Col1,Col2,Col3";
print "$_,$d1{$_},$d2{$_}\n" foreach (keys %k) ;

答案 3 :(得分:0)

我不想合并文件,每种语言必须在一个单独的文件中,但它们必须是文件之间的1对1对应关系。根据我在第一篇文章中讨论的示例,在完成该过程后,文件的内容必须如下:

File1.txt:
EnWord1         
EnWord3
Enword4

File1.txt: EnWord1 EnWord3 Enword4 {{ 1}}

File2.txt:
ArTrans1         
ArTrans3
ArTrans4

File2.txt: ArTrans1 ArTrans3 ArTrans4

正如我在该示例中所解释的,EnWord1,EnWord3和EnWord4是File1.txt和File3.txt中的常用英语单词。

中间必须保留的重要一点是File1和File3都是英文,它们共享一些单词。我需要首先找到这些文件的公共行并将它们存储在另一个文件(比如File5.txt)中,然后过滤File2和File4,它们只包含存储在File5中的单词的翻译。