请求完善Perl脚本:新增水果与信息存在性校验功能
Perl脚本功能完善需求与实现
需求说明
需要为现有Perl脚本新增功能:检查命令行传入的水果(fruit)和对应信息(info)是否同时存在于目标文件中,同时满足以下3项要求:
- 若命令行传入的水果不存在于文件中,则将该水果及对应信息添加至文件;
- 若命令行传入的水果已存在于文件中,但对应信息未存在,则将信息添加至该水果条目下;
- 若命令行传入的水果及对应信息均已存在于文件中,则跳过该条目。
命令行示例
<script> -fruit apple,orange,jackfruit -info y,c,a
原文件内容
apple x y orange a b
预期输出
(因apple和y已存在,故跳过)
apple x y orange a b c jackfruit a
现有代码
use strict; use warnings; use Tie::File; my $help=0; my $info; my $fruit; use Getopt::Long; if (! GetOptions( "fruit=s" => \$fruit, "info=s" => \$info, )){ print "\nEntered Arguments are not enough!\nPlease Use Switch '-help' or '-h' For More Information.\n"; exit; } my $split_info; my $split_fruit; my @split_info = split(',', $info); my @split_fruit = split(',', $fruit); my %new_data; @new_data{@split_fruit}=@split_info; tie my @file, 'Tie::File', "/nfs/site/disks/ipg_da_00003/ip7nm/sungyuan/script/regression_indicator/testing/2022.12.SP1/config.txt" or die $!; for (0 .. $#file) { next if /^\s/; if (exists $new_data{$file[$_]}) { splice @file, $_ + 1, 0, "\t$new_data{$file[$_]}\n"; # Delete our current key/value pair from the hash delete $new_data{$file[$_]}; } } # For each key left in the hash... for (keys %new_data) { # Push two new lines into our tied file array # (This adds new lines to the end of the file) push @file, "$_\n", "\t$new_data{$_}\n"; }
修改后的代码
use strict; use warnings; use Tie::File; my $help=0; my $info; my $fruit; use Getopt::Long; if (! GetOptions( "fruit=s" => \$fruit, "info=s" => \$info, )){ print "\n参数不足!请使用 '-help' 或 '-h' 获取更多信息。\n"; exit; } my @split_info = split(',', $info); my @split_fruit = split(',', $fruit); # 将输入的水果和信息转为哈希集合,键为"fruit:info"的形式,方便查重 my %input_pairs; for my $i (0 .. $#split_fruit) { next unless exists $split_info[$i]; # 处理水果和信息数量不匹配的情况 $input_pairs{"$split_fruit[$i]:$split_info[$i]"} = 1; } tie my @file, 'Tie::File', "/nfs/site/disks/ipg_da_00003/ip7nm/sungyuan/script/regression_indicator/testing/2022.12.SP1/config.txt" or die $!; my $current_fruit; my %existing_pairs; # 第一步:遍历文件,记录已存在的fruit-info配对 for my $line (@file) { chomp $line; $line =~ s/^\s+|\s+$//g; # 去除前后空白字符 next if $line eq ''; if ($line !~ /^\s/) { # 识别水果名称行 $current_fruit = $line; } else { # 识别信息行 my $info_item = $line; $existing_pairs{"$current_fruit:$info_item"} = 1 if $current_fruit; } } # 第二步:遍历输入配对,处理需要添加的内容 my %remaining_fruits; # 记录需要新增的水果及其信息 for my $i (0 .. $#split_fruit) { my $f = $split_fruit[$i]; my $inf = $split_info[$i] // ''; next unless $inf; my $pair_key = "$f:$inf"; if (exists $existing_pairs{$pair_key}) { next; # 配对已存在,跳过 } elsif (grep { /^\s*$f\s*$/ } @file) { # 水果存在但信息不存在,需要插入信息 my $insert_pos; # 找到该水果行的位置,在其后插入信息 for my $idx (0 .. $#file) { chomp $file[$idx]; if ($file[$idx] =~ /^\s*$f\s*$/) { # 找到水果行,从下一行开始找第一个非信息行的位置,或者直接插在水果行后 $insert_pos = $idx + 1; # 跳过已有的信息行,找到插入点(直到空行或下一个水果) while ($insert_pos <= $#file && $file[$insert_pos] =~ /^\s/) { $insert_pos++; } splice @file, $insert_pos, 0, "\t$inf\n"; last; } } } else { # 水果不存在,加入待新增列表 $remaining_fruits{$f} = $inf; } } # 第三步:新增不存在的水果及其信息 for my $f (keys %remaining_fruits) { push @file, "\n$f\n", "\t$remaining_fruits{$f}\n"; }
代码修改说明
- 输入数据处理:将命令行传入的水果和信息组合成
fruit:info格式的键存入哈希,方便后续查重。 - 文件内容扫描:遍历文件,识别水果名称和对应的信息,记录所有已存在的
fruit:info配对。 - 配对检查与处理:
- 若配对已存在,直接跳过;
- 若水果存在但信息不存在,找到该水果条目位置,插入新信息;
- 若水果不存在,加入待新增列表,最后统一添加到文件末尾。
- 边界处理:考虑了水果和信息数量不匹配的情况,避免报错。
内容的提问来源于stack exchange,提问作者Blurman
相关产品推荐
相关产品推荐

