Perl glob未匹配到预期文件问题排查求助
Perl处理文件路径时第二行匹配失败问题
问题说明
使用Perl脚本读取new.txt中的每行路径,通过glob匹配对应路径下的wint_nightly_nfarm_*.main.20241216.4262507文件,再提取文件名中的bankName,但new.txt第二行始终无法正确匹配,输出为空,需解决该问题以得到预期结果。
现有代码
my $bankNameTest; my $bankName; my @lines; my $document = do { local $/ = undef; open my $fh, "<", "new.txt" or die "could not open $file: $!"; <$fh>; }; chomp ($document); print "$document is doc\n"; @lines = split (/ /,$document); foreach my $test (@lines) { $bankNameTest=glob ("${test}/wint_nightly_nfarm_*.main.20241216.4262507") ; chomp ($bankNameTest); print "$bankNameTest is testbankname\n"; $bankName=`ls -d $bankNameTest | sed -r "s?${var}/??g" | sed -r "s/wint_nightly_nfarm_//g" | sed -r "s/.main.20241216.4262507//g"`; chomp ($bankName); print "$bankName is the bankName\n"; }
new.txt内容
_qa/SERVFARM/CAPTURE_DB/CaptureViewer/2487964_brd_launch/cap_allegro_view _qa/SERVFARM/CAPTURE_DB/CaptureViewer/FIND/enh_find/DRC_MARKERS/hierdsn_incomp_entry _qa/SERVFARM/CAPTURE_DB/CaptureViewer/crossprobe/03_between_cap_allegroviewer/dsn_schm_page
当前输出
_qa/SERVFARM/CAPTURE_DB/CaptureViewer/2487964_brd_launch/cap_allegro_view/wint_nightly_nfarm_capture_viewer.main.20241216.4262507 is testbankname capture_viewer is the bankName is testbankname is the bankName _qa/SERVFARM/CAPTURE_DB/CaptureViewer/crossprobe/03_between_cap_allegroviewer/dsn_schm_page_and_part_name_with_special_chars/wint_nightly_nfarm_capture_viewer.main.20241216.4262507 is testbankname capture_viewer is the bankName
预期输出
_qa/SERVFARM/CAPTURE_DB/CaptureViewer/2487964_brd_launch/cap_allegro_view/wint_nightly_nfarm_capture_viewer.main.20241216.4262507 is testbankname capture_viewer is the bankName _qa/SERVFARM/CAPTURE_DB/CaptureViewer/FIND/enh_find/DRC_MARKERS/hierdsn_incomp_entry/wint_nightly_nfarm_capture_viewer.main.20241216.4262507 is testbankname capture_viewer is the bankName _qa/SERVFARM/CAPTURE_DB/CaptureViewer/crossprobe/03_between_cap_allegroviewer/dsn_schm_page_and_part_name_with_special_chars/wint_nightly_nfarm_capture_viewer.main.20241216.4262507 is testbankname capture_viewer is the bankName
问题根源与解决方案
问题1:换行符处理错误
原脚本一次性读取整个文件后用硬编码换行符拆分,且仅对整个文档做一次chomp,若文件包含Windows风格的\r\n换行,chomp只会去掉\n,导致部分行末尾残留\r,glob无法匹配带\r的路径。
问题2:未定义变量$var
脚本中使用了未定义的$var变量,导致sed命令执行异常,影响bankName提取。
问题3:不必要的系统调用
使用ls和sed等系统命令处理字符串,既低效又存在shell注入风险,完全可以用Perl内置字符串操作替代。
修改后的代码
use strict; use warnings; my $target_pattern = 'wint_nightly_nfarm_*.main.20241216.4262507'; open my $fh, '<', 'new.txt' or die "无法打开new.txt: $!"; while (my $test = <$fh>) { chomp $test; # 去掉每行末尾的所有换行符(包括\r\n或\n) next if $test =~ /^\s*$/; # 跳过空行 my ($bankNameTest) = glob("$test/$target_pattern"); if ($bankNameTest) { print "$bankNameTest is testbankname\n"; # 用Perl正则提取bankName,替代系统调用 if ($bankNameTest =~ m{wint_nightly_nfarm_(.*)\.main\.20241216\.4262507$}) { my $bankName = $1; print "$bankName is the bankName\n"; } else { print "无法提取bankName: $bankNameTest\n"; } } else { print "未找到匹配文件: $test/$target_pattern\n"; } } close $fh;
代码说明
- 启用
strict和warnings,提前发现语法和变量问题。 - 逐行读取文件,每行单独chomp,彻底处理不同系统的换行符。
- 用Perl正则直接从匹配到的文件路径中提取bankName,避免系统调用。
- 增加空行判断和错误提示,提升脚本健壮性。
内容的提问来源于stack exchange,提问作者AskQuestionsP
相关产品推荐
相关产品推荐

