如果非空文件比较列并将匹配行写入新文件

时间:2013-08-09 13:39:26

标签: perl

我想编写一个执行以下操作的脚本:用户可以选择导入.txt文件(为此我编写了代码)(这里是$list1)。此文件只包含一列,每行都有名称。如果用户导入的文件非空,那么我想将来自另一个文件(此处为$file2)的列中的名称与导入文件中的名称进行比较。我有一个匹配项,那么原始文件($file2)的整行应该放在一个新文件中($filter1)。

这是我到目前为止所做的:

my $list1;

if (prompt_yn("Do you want to import a genelist for filtering?")){
    my $genelist1 = prompt("Give the name of the first genelist file:\n");
    open($list1,'+<',$genelist1) or die "Could not open file $genelist1 $!";
}

open(my $filter1,'+>',"filter1.txt") || die "Can't write new file: $!";

my %hash1=();
while(<$list1>){ # $list1 is the variable from the imported .txt file
    chomp;    
    next unless -z $_;
    my $keyfield= $_; # this imported file contains only one column
    $hash1{$keyfield}++;
}

seek $file2,0,0; #cursor resetting
while(<$file2>){ # this is the other file with multiple columns
    my @line=split(/\t/);  # split on tabs
    my $keyfield=$line[2]; # values to compare are in column 3       
    if (exists($hash1{$keyfield})){
    print $filter1 $_;
    }       
}   

运行此脚本时,我的输出filter1.txt为空。哪个不正确,因为列之间肯定有匹配。

1 个答案:

答案 0 :(得分:1)

因为你已经将$ list1文件句柄声明为块内的词法(“my”)变量,所以它只在该块中可见。

因此,脚本中的后续行无法看到$ list1,并且它会提供错误消息

要解决此问题,请在打开文件的if ..块之前声明$ list1

如脚本所示,不在%hash1

中设置键或值

您的规范很模糊,但您可能打算从file1

加载hash1密钥
while(<$list1>){            # $list1 is the variable from the imported .txt file
    chomp;                  # remove newlines
    my $keyfield=$_;        # this imported file contains only one column
    $hash1{$keyfield}++;    # this sets a key in %hash1
    }

然后在浏览file2时

while(<$file2>){                      # this is the other file with multiple columns
    my @line=split(/\t/);             # split on tabs
    my $keyfield=$line[2];            # values to compare are in column "2"      
    if (exists($hash1{$keyfield}) ){  # do hash lookup for exact match
        print $_;                     # output entire line
    } 

顺便提一下,$ line [2]实际上是第3列,第一列是$ line [0],第二列是$ [1]等

如果你真的想要进行部分或模式匹配(比如grep),那么使用哈希是不合适的

最后,您必须修改print $_; # output entire line以输出到文件,如果这是您需要的。我删除了对$ filter1的引用,因为这未在显示的脚本片段中声明