我有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
答案 0 :(得分: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
,使用数组元素作为键并使用唯一数字作为值。对于%ahash
,这些ID与行号相同。您可以将%bhash
中的ID视为具有偏移量的行号。
然后我收集散列之间不同的所有键值对。为此,我会在%ahash
和%bhash
中列出所有键。对于这些密钥中的每一个,我测试两个哈希中是否存在此密钥(我不使用exists
,而是对值进行测试,因为我可以保证不会分配具有错误值的ID-除0
之外的所有数字都评估为真。如果两个哈希中都存在密钥,则返回空列表()
。如果密钥只存在于其中一个哈希中,我将返回一个包含密钥和值的双元素列表,该列表位于%ahash
或%bhash
中。
在下一步中,我按照相关值按升序对所有不同的键进行排序,并按{C-1}}的顺序存储键。您可以将它们打印到文件中,我只需将它们转储,然后输出:
@sorted
我相信这符合您的标准。
基本上,你有一个非常优雅的算法来找到差异,但你并没有包含排序数据,就像我使用ID这样的行号一样。
在大多数情况下,使用带有$VAR1 = [
'cars',
'bikes',
'vehicle',
'hawk',
'hero'
];
的词法文件句柄比使用全局文件句柄更受欢迎。此外,my
的三参数形式更灵活,值得习惯。例如,我将第三行写成
open
但是再一次,TIM TOWTDI。
答案 1 :(得分: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
>
答案 2 :(得分:0)
由于数据存储为哈希引用,因此不保留顺序。见How can I print a Perl hash in specific order?
答案 3 :(得分:0)
$ diff a.txt b.txt
$不是代码的一部分,它用于表示bash命令提示符。
comm也可能对你有用。