2015-09-21 4 views
1

Я хочу просмотреть все файлы в каталоге, за исключением файлов, заканчивающихся на .py. Строка в существующий сценарий является:Исключая файл с perl grep

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

И я хочу что-то вроде:

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

Можете ли вы помочь с точным синтаксисом?

ответ

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); 
1

grep использует регулярные выражения, а не шарики (ака маски). Правильный синтаксис

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

perl's build in 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/*"); 
Смежные вопросы