perl to print lines with matching fields from two files, error: use of uninitialized value in string
perl to print lines with matching fields from two files, error: use of uninitialized value in string
我有两个文件,它们看起来像:
文件 1:
chr id position a0 a1
22 rs4820378:39869209:C:T 39869209 C T
22 22:16050075:A:G 16050075 A G
22 22:16050115:G:A 16050115 G A
22 rs199694733:39913976:C:CT 39913976 C CT
22 rs139408809:39937958:GC:G 39937958 GC G
文件 2:
SNP CHR BP A1 A2
rs4820378 22 39869209 C T
rs4821900 22 39869719 G A
rs1984662 22 39869997 T G
rs35629588 22 39913976 I2 D
rs139408809 22 39937958 D I2
我想找到行
- File1 中的字段 1 和 3 与 File2 中的字段 2 和 3 匹配
还有
File1 中的字段 4 和 5 与 File2 中的字段 4 和 5 匹配
两个文件的字段 4 超过 1 个字符
两个文件的字段 5 都超过 1 个字符
然后从 File1 打印字段 2,从 File2 打印字段 1 和 3
下面的代码
#! perl -w
use strict;
use warnings;
my %kglocus;
open( my $loci_in, "<", "File1" ) or die $!;
while ( <$loci_in> ) {
next if m/chr/;
my ( $CHR, $id, $BP, $A1, $A2 ) = split;
my $reg = "${CHR}_$BP";
$kglocus{$reg} = [ $CHR, $id, $BP, $A1, $A2 ];
}
close $loci_in;
my $filename = shift @ARGV;
open( my $input, "<", $filename ) or die $!;
while ( <$input> ) {
next if m/SNP/;
my ( $SNP, $CHR, $BP, $A1, $A2 ) = split;
my $reg = "${CHR}_$BP";
if ( $A1 eq $kglocus{$reg}->[3] and $A2 eq $kglocus{$reg}->[4] ) {
print "$kglocus{$reg}->[1] $SNP $BP\n";
}
elsif ( ( length( $A1 ) > 1 && length( $kglocus{$reg}->[3] ) > 1 ) ||
( length( $A2 ) > 1 && length( $kglocus{$reg}->[4] ) > 1 ) ) {
print "$kglocus{$reg}->[1] $SNP $BP\n";
}
}
close( $input );
我收到以下所有输入行的错误:
Use of uninitialized value in string eq at find_ID.hash.chr22.pl line 23
Use of uninitialized value in length at find_ID.hash.chr22.pl line 27
谁能指出问题所在?
问题是散列元素$kglocus{$reg}
的存在构成了第一个测试,即"Fields 1 and 3 from File1 match fields 2 and 3 from File2"。但是您将其视为该测试始终通过,并简单地使用它来访问 File1
记录
的元素
你需要像 next unless $kglocus{$reg}
这样的东西才能让它正常工作。我也希望看到该值作为一个单独的变量被提取出来,以避免一遍又一遍地索引散列
这是适合您的解决方案
use strict;
use warnings;
use v5.10.1;
use autodie;
my %kglocus;
{
open my $in_fh, '<', 'File1';
while ( <$in_fh> ) {
next if /chr/;
my ( $chr, $id, $bp, $a1, $a2 ) = split;
my $key = "${chr}_$bp";
$kglocus{$key} = [ $chr, $id, $bp, $a1, $a2 ];
}
}
{
my ( $filename ) = @ARGV;
open my $in_fh, '<', $filename;
while ( <$in_fh> ) {
next if /SNP/;
my ( $snp, $chr, $bp, $a1, $a2 ) = split;
my $key = "${chr}_$bp";
next unless my $item = $kglocus{$key};
if ( $a1 eq $item->[3] and $a2 eq $item->[4]
or length $a1 > 1 and length $item->[3] > 1
or length $a2 > 1 and length $item->[4] > 1 ) {
print "$item->[1] $snp $bp\n";
}
}
}
我有两个文件,它们看起来像:
文件 1:
chr id position a0 a1
22 rs4820378:39869209:C:T 39869209 C T
22 22:16050075:A:G 16050075 A G
22 22:16050115:G:A 16050115 G A
22 rs199694733:39913976:C:CT 39913976 C CT
22 rs139408809:39937958:GC:G 39937958 GC G
文件 2:
SNP CHR BP A1 A2
rs4820378 22 39869209 C T
rs4821900 22 39869719 G A
rs1984662 22 39869997 T G
rs35629588 22 39913976 I2 D
rs139408809 22 39937958 D I2
我想找到行
- File1 中的字段 1 和 3 与 File2 中的字段 2 和 3 匹配
还有
File1 中的字段 4 和 5 与 File2 中的字段 4 和 5 匹配
两个文件的字段 4 超过 1 个字符
两个文件的字段 5 都超过 1 个字符
然后从 File1 打印字段 2,从 File2 打印字段 1 和 3
下面的代码
#! perl -w
use strict;
use warnings;
my %kglocus;
open( my $loci_in, "<", "File1" ) or die $!;
while ( <$loci_in> ) {
next if m/chr/;
my ( $CHR, $id, $BP, $A1, $A2 ) = split;
my $reg = "${CHR}_$BP";
$kglocus{$reg} = [ $CHR, $id, $BP, $A1, $A2 ];
}
close $loci_in;
my $filename = shift @ARGV;
open( my $input, "<", $filename ) or die $!;
while ( <$input> ) {
next if m/SNP/;
my ( $SNP, $CHR, $BP, $A1, $A2 ) = split;
my $reg = "${CHR}_$BP";
if ( $A1 eq $kglocus{$reg}->[3] and $A2 eq $kglocus{$reg}->[4] ) {
print "$kglocus{$reg}->[1] $SNP $BP\n";
}
elsif ( ( length( $A1 ) > 1 && length( $kglocus{$reg}->[3] ) > 1 ) ||
( length( $A2 ) > 1 && length( $kglocus{$reg}->[4] ) > 1 ) ) {
print "$kglocus{$reg}->[1] $SNP $BP\n";
}
}
close( $input );
我收到以下所有输入行的错误:
Use of uninitialized value in string eq at find_ID.hash.chr22.pl line 23
Use of uninitialized value in length at find_ID.hash.chr22.pl line 27
谁能指出问题所在?
问题是散列元素$kglocus{$reg}
的存在构成了第一个测试,即"Fields 1 and 3 from File1 match fields 2 and 3 from File2"。但是您将其视为该测试始终通过,并简单地使用它来访问 File1
记录
你需要像 next unless $kglocus{$reg}
这样的东西才能让它正常工作。我也希望看到该值作为一个单独的变量被提取出来,以避免一遍又一遍地索引散列
这是适合您的解决方案
use strict;
use warnings;
use v5.10.1;
use autodie;
my %kglocus;
{
open my $in_fh, '<', 'File1';
while ( <$in_fh> ) {
next if /chr/;
my ( $chr, $id, $bp, $a1, $a2 ) = split;
my $key = "${chr}_$bp";
$kglocus{$key} = [ $chr, $id, $bp, $a1, $a2 ];
}
}
{
my ( $filename ) = @ARGV;
open my $in_fh, '<', $filename;
while ( <$in_fh> ) {
next if /SNP/;
my ( $snp, $chr, $bp, $a1, $a2 ) = split;
my $key = "${chr}_$bp";
next unless my $item = $kglocus{$key};
if ( $a1 eq $item->[3] and $a2 eq $item->[4]
or length $a1 > 1 and length $item->[3] > 1
or length $a2 > 1 and length $item->[4] > 1 ) {
print "$item->[1] $snp $bp\n";
}
}
}