1

我的 Perl 脚本搜索文件名目录,使用grep仅输出名称中不包含数字 2-9 的文件名。这意味着,如预期的那样,也将返回以数字“1”结尾的文件名。但是,我想使用chop函数输出这些没有“1”的文件名,但不知道如何。也许可以将grepChop函数组合在一行代码中来实现这一点?请指教。谢谢。

这是我的 Perl 脚本:

#!/usr/bin/perl
use strict;
use warnings;

my $dir = '/Users/jdm/Desktop/xampp/htdocs/cnc/images/plants';
opendir(DIR, $dir);
@files = grep (/^[^2-9]*\.png\z/,readdir(DIR));

foreach $file (@files) {
   print "$file\n";
}

这是输出:

Ilex_verticillata.png
Asarum_canadense1.png
Ageratina_altissima.png
Lonicera_maackii.png
Chelone_obliqua1.png

这是我想要的输出,从文件名的末尾删除了数字“1”:

Ilex_verticillata.png
Asarum_canadense.png
Ageratina_altissima.png
Lonicera_maackii.png
Chelone_obliqua.png
4

2 回答 2

6

要删除的数字1在扩展名之前的名称末尾;这与完全过滤数字(2-9)不同,我不会尝试将其放入一个操作中。

相反,一旦你有了过滤列表(名称中没有 2-9),然后剪掉1. 看到所有感兴趣的名称都.png可以简单地使用正则表达式

$filename =~ s/1\.png\z/.png/;

如果在字符串不变之前没有1权利。.png如果可能涉及其他扩展名,那么您应该使用模块来分解文件名。

要合并这一点,您可以grep通过map

opendir my $dfh, $dir  or die "Can't open $dir: $!";

my @files = 
    map { s/1\.png\z/.png/r } 
    grep { /^[^2-9]*\.png\z/ } 
    readdir $dfh;

我还引入了词汇目录文件句柄而不是 glob,并添加了对是否opendir有效的检查。/r需要替换 in的修饰符,map以便返回字符串(如果正则表达式不匹配,则更改或不变),而不是根据需要在适当的位置更改。

但是,这会两次传递文件名列表,而可以使用直接循环。原则上可能会影响性能;但是,这里所有的操作都是在列表的每个元素上完成的,因此性能差异很小。

于 2020-10-08T19:36:40.807 回答
5

您可以使用以下内容:

s/1//g for @files;

也可以使用map.

my @files =
   map s/1//rg,
      grep /^[^2-9]*\.png\z/,
         readdir(DIR);
于 2020-10-08T19:36:16.290 回答