调试perl分配



作为这个问题的背景,我应该解释一下,我不懂任何Perl,并且对正则表达式过敏(我们都有弱点(。我正试图弄清楚为什么Perl程序不接受我输入的数据。我不需要深入了解这个程序——我只是在做时间比较。

考虑一下这个赋值语句:

($sample_ls_id) = $sample_ls_id =~ /:ww(d+):/;

如果我理解正确的话,它就是检查sample_ls_id是否与某个正则表达式匹配,如果匹配,则分配整个字符串,或者类似的东西。

然而,我不明白这是怎么回事。根据文件,即perldoc perlretut,我简要查看了

$sample_ls_id =~ /:ww(d+):/

如果匹配,只返回true或false。

我试图匹配的字符串看起来像

1000    10      0       0       1        urn:lsid:dcc.hapmap.org:Individual:CEPH1000.10:1        urn:lsid:dcc.hapmap.org:Sample:SAMPLE1:1

此操作失败,出现错误

Use of uninitialized value $sample_ls_id in concatenation (.) or string
at database/populate/family.pl line 38, <INPUT> line 1.

第38行为

print OUTPUT "$sample_ls_idt$family_ped_idt$individual_ped_idt$father_ped_idt$mother_ped_idt$sext$created_byt$population_coden";

请参阅下面的完整脚本。然而,显然非常相似的字符串

1420    9       0       0       1       urn:lsid:dcc.hapmap.org:Individual:CEPH1420.09:1  urn:lsid:dcc.hapmap.org:Sample:NA12003:1

似乎通过了。

就上下文而言,整段代码是:

use strict;
use warnings;
use Getopt::Long;
my $input_file = "data/family_ceu.txt";
my $output_file = "sql/family_ceu.sql";
my $population_code = "CEU";
GetOptions ('i=s' => $input_file,
            'o=s' => $output_file,
            'p=s' => $population_code
            );
usagecheck();
my $created_by = 'gwas_analyzer';
print "Creating SQL file for inserting family data from $input_filen";
open (INPUT, "< $input_file");
open (OUTPUT, "> $output_file");
print OUTPUT "INSERT INTO population (population_code, private) VALUES ('$population_code', 'f');n";
print OUTPUT "COPY family (ls_id, family_ped_id, individual_ped_id, father_ped_id, mother_ped_id, sex, created_by, population_code) FROM stdin;                      
";
while (my $line = <INPUT>)
{
    chomp $line;
    #Skip any comment lines 
    next if($line =~ /^#/);
    my ($family_ped_id, $individual_ped_id, $father_ped_id, $mother_ped_id, $sex, $individual_ls_id, $sample_ls_id) = split (/t/, $line);
    ($sample_ls_id) = $sample_ls_id =~ /:ww(d+):/;
    print OUTPUT "$sample_ls_idt$family_ped_idt$individual_ped_idt$father_ped_idt$mother_ped_idt$sext$created_byt$population_coden";
}
print OUTPUT "\.n";
close OUTPUT;
sub usagecheck
{
    if (!$input_file || !$output_file || !$population_code)
    {
        print "Missing argument (see required arguments below):n";
        usage();
        exit;
    }
}
sub usage
{
    print "perl family.pl -i <input file> -o <output file> -p <population code>n";
}

如果你知道正则表达式和Perl,我相信这是一个非常简单的问题。

$sample_ls_id = 'urn:lsid:dcc.hapmap.org:Sample:SAMPLE1:1';

正则表达式"/:\w\w(\d+(:/;"失败。当字符串后面有冒号":"one_answers"word"字符"\w"时,此正则表达式将通过,另一个"单词"字符'\w',后跟一个或多个数字'\d+'和冒号':'。

$sample_ls_id = 'urn:lsid:dcc.hapmap.org:Sample:NA12003:1';

正则表达式"/:\w\w(\d+(:/;"在中找到匹配项':NA12003:'。(冒号、2个单词字符、数字和一个冒号(。

my $sample_id = 'urn:lsid:dcc.hapmap.org:Sample:NA12003:1'
($sample_ls_id) = $sample_ls_id =~ /:ww(d+):/;

"($sample_ls_id("捕获匹配的"(\d+("部分(也存储在$1中(,在本例中为12003。

您在前面的示例中遇到了一个错误,因为正则表达式失败并且未定义"($sample_ls_id("。

在列表上下文中,例如对($sample_ls_id)的赋值,=~返回捕获的列表。它可以将提取$1等保存在一个单独的语句中。

与其将字符串本身存储回自身,不如使用捕获。\d由1美元持有,所以只需将代码更改为这样的代码:

$sample_ls_id =~ /:ww(d+):/; # no letters before implies "match"
$sample_ls_id = $1; # I assume that $1 will be empty if no match, I'm not 100% on this.

我不知道你为什么会出现这样的错误,但你的代码似乎会像上面一样更有意义。

这可能与输入没有最后一个元素有关(例如,您有A:B:C,但您需要A:B:C:D将D存储在示例ls-id中,如果D丢失,则它永远不会初始化,然后regex就没有意义了。(

此外,我们没有所有的代码(第38行看起来与while循环中的第一行相对应(,如果你发布更多可能会有所帮助。

最新更新