2013-06-10 3 views
3

Я использую Perl для захвата имен файлов в некоторых указанных папках, в которых есть определенные слова. Ключевыми словами в этих именах файлов являются «предложения» или «очищенные» и «regup» или «regdn». Другими словами, одно из «предложений» или «очищено», и один из «regup» или «regdn» должен появиться в имени файла, чтобы быть положительным. Эти два слова могут быть в любом порядке, и есть символы/слова, которые появятся перед ними и за ними. Соответствующий образец имя файл:Эффективное соответствие набора имен файлов с регулярным выражением в Perl

2day_Agg_AS_Offers_REGDN-09-JUN-11.csv 

У меня есть регулярное выражение, которое успешно захватывает каждый из совпавших имен файлов как полный путь, который является тем, что я хотел, но это, кажется, безвкусные и неэффективно. Попытки получить немного лучший код не удались.

Работая подход:

# Get the folder names 
my @folders = grep /^\d{2}-/, readdir DIR; 

foreach my $folder (@folders) { 
    # glob the contents of the folder (to get the file names) 
    my @contents = <$folder/*>; 

    # For each filename in the list, if it matches, print it 
    foreach my $item (@contents) { 
     if ($item =~ /^$folder(?=.*(offers|cleared))(?=.*(regup|regdn)).*csv$/i){ 
      print "$item\n"; 
     } 
    } 
} 

Покушение на что-то более короткий/очиститель:

foreach my $folder (@folders) { 
    # glob the contents of the folder (to get the file names) 
    my @contents = <$folder/*>; 

    # Seems to determine that there are four matches in each folder 
    # but then prints the first matching filename four times 
    my $single = join("\n", @contents); 
    for ($single =~ /^$folder(?=.*(offers|cleared))(?=.*(regup|regdn)).*csv$/im) { 
     print "$&\n";#"Matched: |$`<$&>$'|\n\n"; 
    } 
} 

Я пробовал другие форматирование с помощью регулярного выражения, используя другие варианты (/ IMG,/мкг, и т.д.) и отправки вывода регулярного выражения в массив, но ничего не работало должным образом. Я не очень хорош в Perl, поэтому я уверен, что у меня отсутствуют некоторые большие возможности, чтобы сделать эту процедуру более эффективной. Благодаря!

+0

Является ли первый набор слов, которые всегда случаются перед вторым набором? – m0skit0

+0

Не обязательно. Слово из (предлагает | очищено) может появляться до или после (regup | regdn). – trynthink

+2

Почему было бы короче или чище использовать 'join' вместо цикла? Я бы сказал, что это усложняет ситуацию. – TLP

ответ

0

Почему бы это было короче или уборщик использовать объединение вместо цикла? Я бы сказал, что это усложняет ситуацию. То, что вы, кажется, делают это просто сопоставление, свободно на основе условий

  • имя содержит offers или cleared
  • имя содержит regup или regdn
  • имени заканчивается .csv.

Так почему бы не просто сделать это:

if ($file =~ /offers|cleared/i and 
    $file =~ /regup|regdn/i and 
    $file =~ /csv$/i) 

Вы могли бы быть заинтересованы в чем-то вроде этого:

use strict; 
use warnings; 
use File::Find; 

my $dir = "/some/dir"; 
my @files; 
find(sub { /offers|cleared/i && 
      /regup|regdn/i && 
      /csv$/i && push @files, $File::Find::name }, $dir); 

Что бы полностью исключить использование ReadDir и других петель. File::Find является рекурсивным.

+0

Я никогда раньше не использовал модуль File :: Find, но опираясь на его встроенное рекурсивное свойство, довольно красиво. Это работает очень хорошо. – trynthink

+0

Это очень хороший модуль, а также основной модуль в Perl 5. – TLP

1

Собирают только эти имена файлов, которые содержат offers или cleared И regup или regdn

my @contents = grep { /offers|cleared/i && /regup|regdn/i } <$folder/*>; 
+0

Просто, чтобы уточнить, мне действительно нужно пойти еще глубже в дереве файлов, поэтому grep на самом деле вытаскивает папки, которые соответствуют тому, где я хочу посмотреть (папки имеют даты, отформатированные как MM-DD-YYYY, поэтому the \ d {2 } -).Затем я просматриваю каждую из этих папок с первым циклом foreach, следовательно, линия glob только внутри этого цикла. – trynthink

+0

обновленный ответ для файлов папок. –

Смежные вопросы