在grep 表达式中使用chop

Jef*_*eff 1 perl chop

我的 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";
}
Run Code Online (Sandbox Code Playgroud)

这是输出:

Ilex_verticillata.png
Asarum_canadense1.png
Ageratina_altissima.png
Lonicera_maackii.png
Chelone_obliqua1.png
Run Code Online (Sandbox Code Playgroud)

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

Ilex_verticillata.png
Asarum_canadense.png
Ageratina_altissima.png
Lonicera_maackii.png
Chelone_obliqua.png
Run Code Online (Sandbox Code Playgroud)

zdi*_*dim 6

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

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

$filename =~ s/1\.png\z/.png/;
Run Code Online (Sandbox Code Playgroud)

并且如果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;
Run Code Online (Sandbox Code Playgroud)

在那里我还引入了一个词法目录文件句柄而不是一个 glob,并添加了一个检查是否opendir有效。在/r对替代修改map是必须的,从而返回字符串(改变或保持不变,如果正则表达式不匹配),并在适当位置没有改变,这里需要。

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


ike*_*ami 5

您可以使用以下内容:

s/1//g for @files;
Run Code Online (Sandbox Code Playgroud)

也可以使用 将解决方案集成到您的链中map

my @files =
   map s/1//rg,
      grep /^[^2-9]*\.png\z/,
         readdir(DIR);
Run Code Online (Sandbox Code Playgroud)