使用perl grep

时间:2015-09-21 08:19:58

标签: regex perl grep

我想查看目录中的所有文件,但以' .py'结尾的文件除外。 现有脚本中的行是:

my @files = sort(grep(!/^(\.|\.\.)$/, readdir($dir_h)));

我想要的是:

my @files = sort(grep(!/^(\.|\.\.|"*.py")$/, readdir($dir_h)));

请帮助您准确的语法?

3 个答案:

答案 0 :(得分:1)

grep使用正则表达式,而不是globs(又名通配符)。正确的语法是

my @files = sort(grep(!/^(\.|\.\.|.*\.py)$/, readdir($dir_h)));

或者,没有不必要的括号

my @files = sort grep ! /^(\.|\.\.|.*\.py)$/, readdir $dir_h;

由于正则表达式中的括号不用于捕获,但仅用于优先级,因此可以将它们更改为非捕获:

my @files = sort grep ! /^(?:\.|\.\.|.*\.py)$/, readdir $dir_h;

你可以用许多不同的方式表达同样的东西,例如

/^\.{1,2}$|\.py$/

即。点缀一次或两次,周围没有任何内容,或最后.py

答案 1 :(得分:1)

perl在grep中的构建实际上非常聪明 - 它迭代一个数组,依次对每个元素应用一个条件。它将每个元素设置为$_

这个条件可以是一个简单的正则表达式,但它不一定是。

所以你可以 - 例如:

my @files = grep { -f $_ } readir(DIR); 

但由于-f默认为$_,您还可以:

my @files = grep { -f } readdir (DIR); 

您还可以将正则表达式应用于$_

my @files = grep { not m/\.py$/ } readdir (DIR); 

(注意 - 这与not $_ =~ m/\.py$/相同 - 默认情况下,模式适用于$_

所以你可以做你想做的事:

my @files = sort grep { not m/\.py$/ and -f } readdir (DIR);

虽然注意 - 它将在当前工作目录中工作,而不是用于读取单独的路径。您可以将readdir用于不同的目录,但我个人更喜欢glob - 因为它也填充了路径:

my @files = sort grep { not m/\.py$/ and -f } glob ( "$dir/*" ); 

答案 2 :(得分:0)

检查目录条目是否为files,然后排除那些以.py结尾的目录:

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

my $dir = "/home/me/somedir";

# good examples in the perldoc:
# perldoc -f readdir
opendir(my $DIR, $dir) || die "Unable to open $dir : $!";

# -f checks that it is a plain file ( perldoc perlfunc )
# !~ means does not match ( perldoc perlre )
# m|\.py$| means a match string that ends in '.py'
my @files = sort grep { -f "$dir/$_" && $_ !~ m|\.py$| } readdir($DIR);