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

修复含引用错误的Hash文件并适配i-signal检索脚本

解决Perl脚本处理含自引用条目Hash文件的执行失败问题

我编写了一段Perl脚本,功能是读取my_hash_data.txt文件,检索值为“i-signal”的条目,并将其父键保存到i-signal-output.txt。脚本在测试Hash文件上运行正常,但处理正式大文件时,因为文件里存在'SignalTextTable' => $VAR1->{'VLAN_FAS'}{'NetworkPdus'}这类自引用错误条目,导致脚本执行失败,需要移除这些错误条目来适配原有脚本。

测试可用的Hash示例

$mein_hash = {
               'CORRECT_1' => {
                                'Signalwert' => 'i-signal',
                                'Zeitstempel' => {
                                                   'stempel' => {
                                                                    'Signalwert' => 'new-sig',
                                                                  }
                                                 }
                              },
               'Data' => {
                               'Email' => 'whatever@asdf.com',
                               'CORRECT_2' => {
                                                'Signalwert' => 'i-signal',
                                                'SignalTextTable' => 'asdf',
                         
                                              },
                               'Telefon' => '0123456789'
                             },
               'Alter' => 30,
               'Name' => 'Max Mustermann'
             };

含错误条目的Hash示例

$mein_hash = {
               'CORRECT_1' => {
                                'Signalwert' => 'i-signal',
                                'Zeitstempel' => {
                                                   'stempel' => {
                                                                    'Signalwert' => 'new-sig',
                                    'SignalTextTable' => $VAR1->{'VLAN_FAS'}{'NetworkPdus'},
                                                                  }
                                                 }
                              },
               'Data' => {
                               'Email' => 'whatever@asdf.com',
                               'CORRECT_2' => {
                                                'Signalwert' => 'i-signal',
                                                'SignalTextTable' => 'asdf',
                         
                                              },
                               'Telefon' => '0123456789'
                             },
               'Alter' => 30,
               'Name' => 'Max Mustermann'
             };

原有可正常运行的脚本

use strict;
use warnings;
use Data::Dumper;
use File::Spec;

# standard library
chdir("U:\\tests");

# Searches a hash for a special keyword "i-signal".
my %gefunden;
sub finde_i_signal {
    my ($hash_ref, $parent_key) = @_;

    foreach my $key (keys %$hash_ref) {
        if (ref($hash_ref->{$key}) eq 'HASH') {
            finde_i_signal($hash_ref->{$key}, $key);
        } elsif ($hash_ref->{$key} eq 'i-signal') {
            $gefunden{$parent_key} = 1;
        }
    }
}

# Filename of the .txt file in the same folder
my $datei_name = "mein_hash_data.txt";

# Open and read the .txt file
if (open(my $datei_handle, '<', $datei_name)) {
    local $/;
    my $datei_inhalt = <$datei_handle>;
    close($datei_handle);

    # Remove the surrounding dollar signs and the variable name.
    $datei_inhalt =~ s/^\$mein_hash\s*=\s*//;

    # Convert the content into a hash reference
    my $datei_hash_ref = eval $datei_inhalt;
    die "Invalid format in the file $datei_name" if !$datei_hash_ref || ref($datei_hash_ref) ne 'HASH';

    # Now call the function and pass the hash reference
    finde_i_signal($datei_hash_ref, undef);

    # Save found i-signals in "HASH_i-signal-output.txt
    open(my $file_handle, '>', 'HASH_i-signal-output.txt') or die "Kann die Datei nicht öffnen: $!";
    foreach my $key (keys %gefunden) {
        print $file_handle "$key\n";
    }
    close($file_handle) or die "Error closing the file: $!";
} else {
    die "The file $datei_name could not be opened: $!";
}

解决方案:移除自引用错误条目

问题根源是eval解析自引用代码时失败——$VAR1在当前上下文未定义。我们可以在解析前用正则表达式批量移除这类自引用条目:

在原有脚本的$datei_inhalt =~ s/^\$mein_hash\s*=\s*//;之后添加以下代码:

# 移除所有包含$VAR1->的自引用条目
$datei_inhalt =~ s/^\s*'[^']+'\s*=>\s*\$VAR1->\{[^}]+\}(?:\{[^}]+\})*,\s*//mg;
# 处理可能遗留的末尾逗号(避免解析错误)
$datei_inhalt =~ s/,\s*(\}|\])/$1/g;

修改后的完整脚本

use strict;
use warnings;
use Data::Dumper;
use File::Spec;

# standard library
chdir("U:\\tests");

# Searches a hash for a special keyword "i-signal".
my %gefunden;
sub finde_i_signal {
    my ($hash_ref, $parent_key) = @_;

    foreach my $key (keys %$hash_ref) {
        if (ref($hash_ref->{$key}) eq 'HASH') {
            finde_i_signal($hash_ref->{$key}, $key);
        } elsif ($hash_ref->{$key} eq 'i-signal') {
            $gefunden{$parent_key} = 1;
        }
    }
}

# Filename of the .txt file in the same folder
my $datei_name = "mein_hash_data.txt";

# Open and read the .txt file
if (open(my $datei_handle, '<', $datei_name)) {
    local $/;
    my $datei_inhalt = <$datei_handle>;
    close($datei_handle);

    # Remove the surrounding dollar signs and the variable name.
    $datei_inhalt =~ s/^\$mein_hash\s*=\s*//;

    # 移除所有包含$VAR1->的自引用条目
    $datei_inhalt =~ s/^\s*'[^']+'\s*=>\s*\$VAR1->\{[^}]+\}(?:\{[^}]+\})*,\s*//mg;
    # 处理可能遗留的末尾逗号(避免解析错误)
    $datei_inhalt =~ s/,\s*(\}|\])/$1/g;

    # Convert the content into a hash reference
    my $datei_hash_ref = eval $datei_inhalt;
    die "Invalid format in the file $datei_name" if !$datei_hash_ref || ref($datei_hash_ref) ne 'HASH';

    # Now call the function and pass the hash reference
    finde_i_signal($datei_hash_ref, undef);

    # Save found i-signals in "HASH_i-signal-output.txt
    open(my $file_handle, '>', 'HASH_i-signal-output.txt') or die "Kann die Datei nicht öffnen: $!";
    foreach my $key (keys %gefunden) {
        print $file_handle "$key\n";
    }
    close($file_handle) or die "Error closing the file: $!";
} else {
    die "The file $datei_name could not be opened: $!";
}

说明

  • 第一个正则表达式匹配并移除所有'Key' => $VAR1->{'...'}{'...'},格式的自引用条目,mg修饰符确保跨多行匹配。
  • 第二个正则表达式处理移除条目后可能出现的末尾逗号(比如哈希最后一个元素后的冗余逗号),避免eval解析时语法错误。

内容的提问来源于stack exchange,提问作者Xandl

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 15:53:14