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

修改Perl代码适配多输入文件,实现GNU Makefile自动测试

问题:修改Perl脚本支持指定输入文件,配合Makefile批量测试

现有场景与需求

当前开发项目需用GNU Makefile自动测试Perl程序,测试时要处理不同输入文件。现有Perl脚本仅能读取固定路径的单个输入文件,识别停用词后将非停用词频率表输出到固定路径的out.txt,代码如下:

#!/usr/bin/perl

use strict;
use warnings;

use Lingua::StopWords qw(getStopWords);

my %found;

my $src = '/programu-testavimas/1-dk/trunk/tests/inputs/test.txt';
my $des = '/programu-testavimas/1-dk/trunk/tests/outputs/out.txt';

open(SRC,'<',$src) or die $!;
open(DES,'>',$des) or die $!;
my $stopwords = getStopWords('en');
while( my $line = <SRC> ){
    ++$found{$_} for grep { !$stopwords->{$_} }
            split /\s+/, lc $line;
}
print DES $_, "\t\t", $found{$_}, $/ for sort keys %found;

close(SRC);
close(DES);

目标是通过独立的case.sh脚本为每个测试用例指定不同输入文件,再用Makefile批量执行所有测试用例。现有一个测试用例脚本示例:

#!/bin/sh
perl /programu-testavimas/1-dk/trunk/scripts/test.pl /programu-testavimas/1-dk/trunk/tests/inputs/test.txt > /home/aleksandra/programų-testavimas/1-dk/trunk/tests/outputs/out.txt

曾尝试用glob修改Perl代码,但输出文件为空,修改后的代码片段如下:

open(DES,'>',$des) or die $!;
my $stopwords = getStopWords('en');
for my $file ( glob $src ) {
  open(SRC,'<',$file) or die "$! opening $file";
  while( my $line = <SRC> ){
      ++$found{$_} for grep { !$stopwords->{$_} }
              split /\s+/, lc $line;
  }
  print DES $_, "\t\t", $found{$_}, $/ for sort keys %found;
  close(SRC);
}

close(DES);

解决方案

1. 修改Perl脚本支持命令行参数

将固定的输入/输出路径改为从命令行参数读取,这样每个测试用例可以独立指定文件路径,代码修改如下:

#!/usr/bin/perl

use strict;
use warnings;

use Lingua::StopWords qw(getStopWords);

# 从命令行获取输入、输出文件路径,缺少参数时提示用法
my ($input_file, $output_file) = @ARGV;
die "用法: $0 <输入文件路径> <输出文件路径>" unless defined $input_file && defined $output_file;

my %word_counts;
my $stopwords = getStopWords('en');

# 打开输入文件并处理内容
open(my $src_fh, '<', $input_file) or die "打开输入文件失败 $input_file: $!";
while (my $line = <$src_fh>) {
    # 拆分单词、转小写、过滤停用词后统计频率
    ++$word_counts{$_} for grep { !$stopwords->{$_} } split /\s+/, lc $line;
}
close($src_fh);

# 将统计结果写入输出文件
open(my $des_fh, '>', $output_file) or die "打开输出文件失败 $output_file: $!";
print $des_fh "$_\t\t$word_counts{$_}\n" for sort keys %word_counts;
close($des_fh);

2. 更新测试用例脚本case.sh

修改脚本直接向Perl脚本传递输入、输出文件参数,无需依赖重定向:

#!/bin/sh
PERL_SCRIPT="/programu-testavimas/1-dk/trunk/scripts/test.pl"
INPUT="/programu-testavimas/1-dk/trunk/tests/inputs/test.txt"
OUTPUT="/home/aleksandra/programų-testavimas/1-dk/trunk/tests/outputs/out.txt"

$PERL_SCRIPT "$INPUT" "$OUTPUT"

3. 编写Makefile批量执行测试

假设所有测试用例脚本放在tests/cases/目录下,Makefile内容如下:

# 匹配所有测试用例脚本
TEST_CASES := $(wildcard tests/cases/*.sh)

# 默认目标:运行全部测试
all: $(TEST_CASES)

# 单个测试用例的执行规则
$(TEST_CASES):
	@echo "执行测试用例: $@"
	@chmod +x $@
	@$@

# 清理所有输出文件(可选)
clean:
	rm -f tests/outputs/*.txt

原修改失败原因

  1. 原代码中$src是固定单个文件路径,glob无法匹配多个文件,导致循环未执行;
  2. 即使匹配到文件,每次循环都会打印一次频率表,造成重复输出;
  3. 使用全局文件句柄SRC、DES存在风险,词法文件句柄(my $fh)更安全可靠。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 20:05:16