如何筛选指定日期范围的wrfout文件?Perl代码修正求助
问题描述
我有一批文件名格式如下:
wrfout_d01_2024-02-08_01_00_00 wrfout_d01_2024-02-08_02_00_00 wrfout_d01_2024-02-08_03_00_00 ...
文件名中日期部分的最后两位数字代表当月日期,我需要筛选出1日至10日或11日至20日的文件,但当前筛选11日至20日文件的Perl代码错误选中了1日至20日的所有文件。现有代码如下:
while (my $file=readdir $DIR){ next if -d $file; if($file =~ /^wrfout_$Dom[$kk]/){ foreach(my $ii = 11; $ii <= 20; ++$ii){ next unless($file =~ /^wrfout_$Dom[$kk]_\d{4}-\d{2}-$ii/); copy("$INPUT_DIR[$kk]/$file","$DATA_DIR") or die "Copy failed: $!"; } } }
变量@INPUT_DIR、$DATA_DIR、$DIR已在其他位置定义,请问如何修改代码实现正确筛选?
修正方案
错误原因
现有代码的正则表达式存在匹配漏洞:比如当$ii=11时,-1会被-11的前半部分匹配成功,导致日期为1-10的文件也被误判为符合条件,最终选中了1-20日的所有文件。同时,循环遍历日期的写法冗余且容易出错。
修改后的代码
直接用正则表达式精准匹配日期范围,无需循环遍历:
筛选11日至20日的文件
while (my $file = readdir $DIR) { next if -d $file; # 匹配日期为11-20的文件,确保日期是完整的两位数字 if ($file =~ /^wrfout_$Dom[$kk]_\d{4}-\d{2}-(1[1-9]|20)_/) { copy("$INPUT_DIR[$kk]/$file", "$DATA_DIR") or die "Copy failed: $!"; } }
筛选1日至10日的文件(可选)
如果需要筛选1-10日的文件,对应的正则表达式如下:
while (my $file = readdir $DIR) { next if -d $file; if ($file =~ /^wrfout_$Dom[$kk]_\d{4}-\d{2}-(0?[1-9]|10)_/) { copy("$INPUT_DIR[$kk]/$file", "$DATA_DIR") or die "Copy failed: $!"; } }
逻辑说明
- 正则表达式
(1[1-9]|20):精准匹配11-19(1[1-9])或20(20),确保日期是完整的两位数字,避免和单个数字的日期部分匹配。 - 末尾的
_:匹配日期后的下划线,进一步确保日期部分是独立完整的,防止出现类似-111这类错误匹配。 - 去掉冗余的foreach循环,一次正则匹配完成筛选,代码更简洁高效。
内容的提问来源于stack exchange,提问作者Zilore Mumba
相关产品推荐
相关产品推荐

