You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Perl脚本报错求助:已关闭文件句柄读取+哈希初始化错误

Perl脚本错误修复方案

错误1:readline() on closed filehandle $fh

  • 原因:打开clinical.txt时未验证文件是否成功打开,若文件不存在、路径错误或无读取权限,文件句柄$fh会处于关闭状态,后续读取操作触发报错。
  • 解决方法:在open语句后添加错误检查逻辑,确保文件正常打开:
    open(my $fh_clin, '<', "clinical.txt") or die "无法打开clinical.txt: $!";
    

错误2:Reference found where even-sized list expected

  • 原因:初始化哈希时错误使用{}(该语法用于创建匿名哈希引用),而哈希初始化需要用()传入键值对列表(空列表对应空哈希)。
  • 解决方法:将哈希初始化语句中的{}替换为():
    %hash = ();
    %tested = ();
    %Mut_Count = ();
    

完整修复后的脚本

#!/usr/bin/perl
use Cwd;
use warnings;
use strict; # 强制变量声明,避免全局变量污染

# 读取clinical.txt并添加错误检查
open(my $fh_clin, '<', "clinical.txt") or die "无法打开clinical.txt: $!";
my (@id, @status);
my $line = <$fh_clin>; # 跳过表头行

while($line = <$fh_clin>)
{   
    chomp $line;
    my @fields2 = split(" ", $line);
    push(@id, $fields2[1]);
    push(@status, $fields2[3]);
}
close($fh_clin);

my @flow = grep { -d } glob "*"; 
my $arrSize = @flow;
for (my $p = 0; $p < $arrSize; $p++)
{
    my @files = <"$flow[$p]/*.maf">;
    print $flow[$p],"\n";
    foreach my $file (@files)
    {
        print $file,"\n";
        # 打开MAF文件,使用词法句柄并添加错误检查
        open(my $fh_maf, '<', $file) or die "无法打开$file: $!";
        my (%hash, %tested, %Mut_Count); # 局部哈希自动初始化为空
        my $hyper = 0;

        # 跳过前6行注释/表头
        for (1..6) {
            $line = <$fh_maf>;
        }

        while($line = <$fh_maf>)
        {
            chomp $line;
            my @temp = split("\t", $line);
            my $key = $temp[4]."_".$temp[5]."_".$temp[6]."_".$temp[10]."_".$temp[11]."_".$temp[12]."_".$temp[15];
            push @{$hash{$key}}, "0";
            push @{$Mut_Count{$temp[15]}}, "0";
        }
        close($fh_maf);

        my @nm = split(/\./, $file);
        # 自动创建Results目录
        mkdir "Results" unless -d "Results";
        # 重新打开MAF文件
        open($fh_maf, '<', $file) or die "无法重新打开$file: $!";
        open(my $out1, ">", "Results/".$nm[1]."_Hyper.txt") or die "无法创建输出文件: $!";

        # 跳过前5行
        for (1..5) {
            $line = <$fh_maf>;
        }
        chomp $line;
        my @temp = split(" ", $line);
        my @temp2 = split(",", $temp[1]);
        print $out1 "Gene\tMutation\tType\tdbSNP\tStatus\tPolyphen\tSift";

        for(my $j=0;$j<scalar(@id);$j++){
            my @M = split('-', $id[$j]);
            for(my $i=0;$i<scalar(@temp2);$i++)
            {
                my @N = split('-', $temp2[$i]);
                if(scalar(@{$Mut_Count{$temp2[$i]}}) > 499 && $M[0] eq $N[0] && $M[1] eq $N[1] && $M[2] eq $N[2] && $status[$j] eq 'MSS')
                {
                    print $out1 "\t",$temp2[$i];
                    $hyper++;
                }
            }
        }

        $line = <$fh_maf>; # 跳过第6行
        while($line = <$fh_maf>)
        {
            chomp $line;
            my $hy = 0;
            my @temp = split("\t", $line);
            my $key = $temp[4]."_".$temp[5]."_".$temp[6]."_".$temp[10]."_".$temp[11]."_".$temp[12];
            if(!exists $tested{$key})
            {
                push @{$tested{$key}}, "0";
                print $out1 "\n",$temp[0],"\t",$key,"\t",$temp[8],"\t",$temp[13],"\t",$temp[25],"\t",$temp[72],"\t",$temp[73];
                for(my $i=0;$i<scalar(@temp2);$i++)
                {
                    my $key_full = $temp[4]."_".$temp[5]."_".$temp[6]."_".$temp[10]."_".$temp[11]."_".$temp[12]."_".$temp2[$i];
                    my @L = split('-', $temp2[$i]);
                    for(my $j=0;$j<scalar(@id);$j++){
                        my @O = split('-', $id[$j]);
                        if(scalar(@{$Mut_Count{$temp2[$i]}}) > 499 && $L[0] eq $O[0] && $L[1] eq $O[1] && $L[2] eq $O[2] && $status[$j] eq 'MSS')
                        {
                            if(exists $hash{$key_full})
                            {
                                print $out1 "\t1";
                                $hy++;
                            }
                            else
                            {
                                print $out1 "\t0";
                            }
                        }
                    }
                }
            }
        }
        close($fh_maf);
        close($out1);

        open(my $out3, ">", "Results/".$nm[1]."_Summary.txt") or die "无法创建汇总文件: $!";
        print $out3 "Hypermutated\t$hyper\n";
        close($out3);
    }
}

额外优化说明

  • 添加use strict强制变量声明,避免全局变量引发的潜在问题
  • 使用词法文件句柄替代裸字句柄,提升代码安全性和可读性
  • 为所有文件操作添加错误检查,便于快速定位问题
  • 读取文件后及时关闭句柄,避免资源泄漏
  • 自动创建Results目录,防止因目录不存在导致输出失败
  • 用循环替代重复的行跳过语句,简化代码结构
  • 重命名部分变量提升代码可读性

内容的提问来源于stack exchange,提问作者Aqsa Arshad.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 08:25:27