我想编写一个执行以下操作的脚本:用户可以选择导入.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
为空。哪个不正确,因为列之间肯定有匹配。
答案 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的引用,因为这未在显示的脚本片段中声明