Perl实现:多文件中匹配文本并提取其上方第三行CHOICE后的内容
Perl实现方案
完整脚本
#!/usr/bin/perl use strict; use warnings; # 目标搜索文本 my $target = 'intl_reg.jcl'; # 要处理的目录,当前目录用 '.' my $dir = '.'; # 打开目录 opendir(my $dh, $dir) or die "无法打开目录 $dir: $!"; # 遍历目录中的文件 while (my $file = readdir($dh)) { # 跳过隐藏文件/目录及非普通文件 next if $file =~ /^\./; next unless -f "$dir/$file"; # 打开文件(失败则警告并跳过) open(my $fh, '<', "$dir/$file") or do { warn "无法打开文件 $file: $!"; next; }; # 维护最多3行的缓冲区,用于记录目标行的前几行内容 my @buffer; while (my $line = <$fh>) { chomp $line; # 更新缓冲区:加入当前行,超过3行则移除最旧的一行 push @buffer, $line; shift @buffer if @buffer > 3; # 匹配目标文本 if ($line =~ /\Q$target\E/) { # 确保缓冲区有足够的行(目标行上方存在第三行) if (@buffer == 3) { my $choice_line = $buffer[0]; # 提取CHOICE后的内容 if ($choice_line =~ /^CHOICE\s+(.*)/) { print "$target $1\n"; } } } } close $fh; } closedir($dh);
逐部分解释
1. 基础约束与配置
use strict;和use warnings;:强制语法规范,避免新手常见的未声明变量、拼写错误等问题,同时输出调试警告。$target:定义要搜索的目标文本,\Q$target\E用于避免目标中的特殊字符(比如.、*)被当作正则语法解析,确保精确匹配。$dir:指定要处理的目录,.代表当前目录,可替换为具体路径(如'/d3/locban/arsys')。
2. 目录遍历逻辑
opendir/closedir:打开/关闭目录句柄,失败则终止并提示错误。readdir:逐个获取目录中的条目,通过next跳过隐藏文件、子目录,只处理普通文件。
3. 文件内容处理
@buffer:作为滑动窗口,始终存储最近读取的3行内容,这样当匹配到目标行时,缓冲区的第一行就是它上方第三行。push/shift:维护缓冲区长度不超过3,保证只保留最相关的行数据。
4. 匹配与提取
- 当匹配到目标行时,先检查缓冲区是否有3行(确保存在上方第三行),再用正则
^CHOICE\s+(.*)捕获CHOICE后的所有内容,最后按要求格式输出。
扩展优化建议
- 命令行传参:避免硬编码目标和目录,改为从命令行获取参数:
运行方式:my $target = shift @ARGV or die "请传入目标文本"; my $dir = shift @ARGV || '.';perl script.pl intl_reg.jcl /path/to/your/dir - 递归处理子目录:如果需要遍历子目录,可使用
File::Find模块:use File::Find; find(\&process_file, $dir); sub process_file { return unless -f $_; # 此处放入原文件处理逻辑,当前文件路径用$_表示 } - 去重输出:若同一文件中多次出现目标文本,可在匹配后添加
last;跳出当前文件的循环,只输出第一次匹配结果。
内容的提问来源于stack exchange,提问作者Jonathan
相关产品推荐
相关产品推荐

