如何在Perl中使用map和grep筛选含下划线的文件名?
解决Perl脚本筛选带下划线文件名的问题
嘿,我来帮你搞定这个Perl脚本的问题!你想要让脚本只输出名称包含下划线的PNG文件,现在的语法错误主要是正则表达式的写法出了问题,咱们一步步捋清楚。
首先得说说你修改时踩的两个坑:
- 你在
grep里写的/^_*[^2-9]*\.png\z/i不对,这个正则是匹配开头可能有零个或多个下划线的文件,但你要的是文件名任意位置包含下划线,完全不符合需求; - 你在
map里写的s/*_*1//rg有语法错误,正则里的*是量词,必须跟在具体字符后面(比如.*表示任意字符任意次数),单独写*会直接触发语法报错,其实你原本的map s/1//rg是没问题的,不需要在这里添加下划线相关的处理。
正确的修改方案
核心思路是:在grep环节同时保留原有的筛选规则,再加上“文件名包含下划线”的判断。这里给你两种实现方式:
方案1:用逻辑与组合多个条件
这种方式更清晰,把不同的筛选规则分开写,可读性更强:
#!/usr/bin/perl use strict; use warnings; my $dir = '/Users/jdm/Desktop/xampp/htdocs/cnc/images/plants'; opendir(my $DIR, $dir); # 先筛选原规则的文件,再额外过滤出包含下划线的 my @files = map s/1//rg, grep { /^[^2-9]*\.png\z/i && /_/ } readdir($DIR); foreach my $file (@files) { print "$file\n"; }
方案2:合并成单个正则表达式
如果你喜欢更紧凑的写法,可以把所有条件整合到一个正则里:
#!/usr/bin/perl use strict; use warnings; my $dir = '/Users/jdm/Desktop/xampp/htdocs/cnc/images/plants'; opendir(my $DIR, $dir); # 正则含义:开头无2-9字符,中间至少有一个下划线,结尾是.png(不区分大小写) my @files = map s/1//rg, grep /^[^2-9]*_.*\.png\z/i, readdir($DIR); foreach my $file (@files) { print "$file\n"; }
关键部分解释
grep { /^[^2-9]*\.png\z/i && /_/ }:第一个正则/^[^2-9]*\.png\z/i保留你原来的筛选逻辑(文件名开头不含2-9、是PNG格式且不区分大小写),第二个/_/确保文件名里存在下划线;map s/1//rg:和你原脚本功能一致,全局去掉文件名里的1字符,r修饰符保证返回修改后的字符串而不改变原变量,g表示全局替换。
这样修改后,脚本就只会输出带下划线的PNG文件,不会再出现Asarumcanadense.png这类不符合要求的文件名了。
内容的提问来源于stack exchange,提问作者Jeff
相关产品推荐
相关产品推荐

