我有这两个文件,我想用数字比较它的内容。
文本1:
C_A C_A 0.0000 0.0000 0 0 50 47 100 390
C_A/I0/I0 INV 0.0200 0.2210 0 0 20 200 30 100
C_A/I0/I2 INV 1.0400 0.2210 0 0 530 200 250 261
文本2:
C_A C_A 0.0000 0 0 0 50 47 100 390
C_A/I0/I0 INV 0.0200 0.2213 0 0 20 200 30 100
C_A/I0/I2 INV 1.04 0.2210 0 0 530 200.00 250 261
期望的输出:
C_A/I0/I0 INV has mismatch property.
到目前为止我已经尝试了这个但是我遇到了use of uninitialized value
的错误。请告诉我。感谢您的帮助。
编辑代码:
use strict;
use warnings;
my %ref_data;
open my $fh, '<', 'Text1' or die $!;
while (<$fh>) {
chomp;
my ($occurname, $tempname, @data) = split;
$ref_data{$occurname} = \@data;
}
open $fh, '<', 'Text2' or die $!;
while (<$fh>) {
chomp;
my ($occurname, $tempname, @data1) = split;
my $data = $ref_data{$occurname};
print "$occurname $tempname has mismatch property\n" if
grep { $data1[$_] != $data->[$_] } 0 .. $#data1;
}
}
答案 0 :(得分:2)
也许以下内容会有所帮助:
use strict;
use warnings;
my $file2 = pop;
my %ref_data;
while (<>) {
my ( $occurname, $tempname, @data1 ) = split;
$ref_data{$occurname} = \@data1;
}
push @ARGV, $file2;
while (<>) {
my ( $occurname, $tempname, @data2 ) = split;
my $data1 = $ref_data{$occurname};
for ( 0 .. $#data2 ) {
if ( $data1->[$_] != $data2[$_] ) {
print "$occurname $tempname has mismatch property\n";
last;
}
}
}
用法:>perl script.pl Text1 Text2 [>outFile]
最后一个可选参数将输出定向到文件。
数据集的输出:
C_A/I0/I0 INV has mismatch property
这让Perl处理文件i / o。此外,for
循环用于比较数组内容 - 而不是grep
- 因为如果找到不匹配,它可以快速终止。
答案 1 :(得分:1)
您可以以整数模式打包它们,然后比较打包值..
unpack('s', $val1) != unpack('s', $val2);
来自perldoc的注意事项:但不要指望奇迹:如果打包值超过分配的字节容量,则高位位被静默丢弃,并且解压缩肯定无法将它们从某些神奇的帽子中拉回来。并且,当您使用签名的模板代码(如s)进行打包时,超出的值可能会导致符号位设置,并且解压缩它将巧妙地返回负值。
答案 2 :(得分:1)
while (<$fh>) {
my ($occurname, $tempname, @data1) = split;
my $data = $ref_data{$occurname};
print "$occurname $tempname has mismatch property\n" unless @$data ~~ @data1;
}
如果您的Perl不够新(<5.10.1),请使用TLP的想法。
编辑:添加了匹配数组长度的检查,以便在数组大小不同时扼杀未初始化的值警告。
if (@data1 != @$data || grep { $data1[$_] != $data->[$_] } 0 .. $#data1) {
print "$occurname $tempname has mismatch property\n";
}
请参阅grep
答案 3 :(得分:1)
根据您需要的精确程度,我只需减去两者并测试它是否非常接近于零:
if ( grep { my $delt= $data[$_] - $data1[$_] ; return ( $delt < -1e-16 ) || ( $delt > 1e-16 ) ; } 1..$#data
注意我将范围从0..$data
更改为1..$#data
。您不需要比较文本的第一个字段。