2

数日前、2つのテキストファイルのタグ付けの違いについて質問したところ、すぐに回答されました。

今、私はかなり似た質問がありますが、もう少し複雑です。次の特性を持つ2つのファイルのペアがあります: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)に表示される共通の単語を見つけて、対応する翻訳を除外することです。要するに、私は2つのバイリンガルの英語-アラビア語と英語のフランス語の辞書を使用して、3つの言語の英語-アラビア語-フランス語の辞書を作成しようとしていると言えます。どうすれば可能ですか?

そのようなペアがたくさんあるので(辞書は異なるファイルに保存されているため、各ファイルには単語の一部が含まれており、何らかの理由でファイルをマージして処理することはできません)、コードの速度を追加する必要があります非常に重要であり、私はこれを行うための迅速な方法を探しています。

最後に、Perlでこれを行うためのいくつかのポイント(または場合によっては完全なコード)を教えてください。

よろしく、ハキム

4

4 に答える 4

2

これをヒントと考えてください、私はこれを確認していません

join <(paste file.1 file.2) <(paste file.3 file.4)
于 2012-06-21T10:19:50.490 に答える
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。

于 2012-06-21T15:18:35.267 に答える
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) ;
于 2012-06-21T11:16:12.560 に答える
0

ファイルをマージしたくありません。各言語は別のファイルにある必要がありますが、ファイル間は 1 対 1 で対応している必要があります。最初の投稿で説明した例によると、プロセスを終了すると、ファイルの内容は次のようになります。

File1.txt:
EnWord1         
EnWord3
Enword4

File2.txt:
ArTrans1         
ArTrans3
ArTrans4

File4.txt:
FrTrans1
FrTrans3
FrTrans4

その例で説明したように、EnWord1、EnWord3、および EnWord4 は、File1.txt と File3.txt の両方で一般的な英語の単語です。

中間に留めておかなければならない重要なことは、File1 と File3 の両方がいくつかの単語を共有する英語であるということです。最初にこれらのファイルの共通行を見つけて別のファイル (File5.txt など) に保存し、次に File5 に保存されている単語の翻訳のみが含まれるように File2 と File4 をフィルター処理する必要があります。

于 2012-06-21T11:40:16.550 に答える