2

つまり、2つのファイルがあります

**a.txt**
cars
bikes
bus 
vehicle
atv

**b.txt**
hawk
hero
atv
bus

***result.txt***
cars
bikes
vehicle
hawk
hero

2つのファイルの違いを印刷したい。コードを試してみましたが、ランダムな方法で違いが得られます。ちゃんと順番に表示してほしい。誰でもこれで私を助けることができますか?

use strict;
my %results = ();  

open FILE1, "<a.txt"
    or die "Could not open file: $! \n"; 
while (my $line = <FILE1>) {

    $results{$line}=1; 
} 
close FILE1;  

open FILE2, "<b.txt" 
    or die "Could not open file: $! \n"; 
while (my $line = <FILE2>) {

    $results{$line}++; 
} 
close FILE2;

open OUTFILE, ">>result.txt" 
    or die "Cannot open $outfile for writing \n";
foreach my $line (keys %results) { 

    print OUTFILE $line if $results{$line} == 1; 
} 

close OUTFILE; 
close OUTFILE1;

このコードで得られる出力は

***result.txt***
cars
hawk
bikes
hero
vehicle
4

4 に答える 4

5

ハッシュは要素をランダムな順序で保存するため、位置情報を保持する必要があります。次のソリューションでは、ハッシュ値を使用して一意の ID を保持します。

コード

#!/usr/bin/perl
use strict; use warnings; use Data::Dumper;

my @a = qw( cars bikes bus vehicle atv );
my @b = qw( hawk hero atv bus );

my $i = 0;
my %ahash = map {$_ => ++$i} @a;
my %bhash = map {$_ => ++$i} @b;

my %different = map {
  ($ahash{$_} and $bhash{$_})
    ? ()
    : ($_ => ($ahash{$_} or $bhash{$_}))
} (keys %ahash, keys %bhash);

my @sorted = sort {$different{$a} <=> $different{$b}} keys %different;

print Dumper(\@sorted);

討論

デモンストレーションの目的で、ファイルは使用しませんでしたが、レコードを配列@a@b.

配列要素をキーとして使用し、一意の数値を値として使用して、これらの配列からハッシュを作成%ahashします。%bhashの場合、これらの ID は回線番号%ahashと同じです。の ID は、オフセットのある行番号と考えることができます。%bhash

次に、ハッシュ間で異なるすべてのキーと値のペアを収集します。%ahashそのために、とのすべてのキーのリストを取得します%bhash。これらのキーのそれぞれについて、両方のハッシュでこのキーの存在をテストします (私は を使用しませんexistsが、値に対してテストします。偽の値を持つ ID が割り当てられていないことを保証できるためです。すべての数値0は true と評価されます)。 )。キーが両方のハッシュに存在する場合、空のリストを返します()。キーがハッシュの 1 つだけに存在する場合、キーと値を含む 2 つの要素のリストを返し%ahashます%bhash

次のステップでは、すべての異なるキーを関連付けられた値で昇順に並べ替え、キーをこの順序で に保存します@sorted。あなたはそれらをファイルに出力します.私は単にそれらをダンプし、この出力を得ました:

$VAR1 = [
      'cars',
      'bikes',
      'vehicle',
      'hawk',
      'hero'
    ];

これはあなたの基準を満たしていると思います。

基本的に、違いを見つけるための非常に洗練されたアルゴリズムがありましたが、ID のような行番号で行ったように、並べ替えデータを組み込んでいませんでした。

スタイルノート

ほとんどの場合、グローバル ファイルハンドルを使用するよりもレキシカル ファイルハンドルを使用するmy方が好まれます。また、 の 3 引数形式openはより柔軟で、慣れる価値があります。たとえば、3行目を次のように書きます

my $filename1 = "a.txt";
open my $file1, '<', $filename1 or die qq{Could not open "$filename1": $!\n};

もう一度言いますが、ティム・トウディです。

于 2012-09-18T04:44:11.943 に答える
1
perl -lne '$X{$_}++;if(eof){$a++;}if($a==2){foreach (keys %X){if($X{$_}==1){print $_}}}' file1 file2

以下でテスト:

> cat temp
cars
bikes
bus
vehicle
atv
> cat temp2
hawk
hero
atv
bus
> perl -lne '$X{$_}++;if(eof){$a++;}if($a==2){foreach (keys %X){if($X{$_}==1){print $_}}}' temp temp2
cars
hawk
hero
vehicle
bikes
>
于 2012-09-18T07:02:53.547 に答える
0
$ diff a.txt b.txt

$はコードの一部ではなく、bashコマンドプロンプトを示すためにあります。

commもあなたに役立つかもしれません。

于 2012-09-20T10:11:53.247 に答える
0

データはハッシュ参照として保存されるため、順序は保持されません。特定の順序で Perl ハッシュを出力するにはどうすればよいですか? を参照してください。

于 2012-09-18T03:42:59.153 に答える