Как я могу перечислить файлы в каталоге с определенным шаблоном имени, используя Perl? - PullRequest
1 голос
/ 10 ноября 2009

У меня есть каталог /var/spool, а внутри него каталоги с именем

a  b  c  d  e  f  g  h i  j  k  l  m  n  o  p q  r  s  t  u  v  x  y z

И внутри каждого "каталога букв", каталога с именем "user" и внутри него, много каталогов с именем auser1 auser2 auser3 auser4 auser5 ...

Каждый каталог пользователя содержит почтовые сообщения, а имена файлов имеют следующий формат: 2. 3. 4. 5. и т. Д.

Как я могу перечислить файлы электронной почты для каждого пользователя в каждом каталоге следующим образом:

    /var/spool/a/user/auser1/11.
    /var/spool/a/user/auser1/9.
    /var/spool/a/user/auser1/8.
    /var/spool/a/user/auser1/10.
    /var/spool/a/user/auser1/2.
    /var/spool/a/user/auser1/4.
    /var/spool/a/user/auser1/12.
    /var/spool/b/user/buser1/12.
    /var/spool/b/user/buser1/134.
    /var/spool/b/user/buser1/144.

и т.д.

Мне нужны эти файлы, а затем открыть каждый файл для изменения заголовка и тела. Эта часть у меня уже есть, но мне нужна первая часть.

Я пытаюсь это:

dir = "/var/spool";

opendir ( DIR, $dir ) || die "No pude abrir el directorio $dirname\n";
while( ($filename = readdir(DIR))){
    @directorios1 = `ls -l "$dir/$filename"`;
    print("@directorios1\n");
}
closedir(DIR);

Но не работает так, как мне нужно.

Ответы [ 6 ]

3 голосов
/ 10 ноября 2009

Вы можете использовать Файл :: Найти .

2 голосов
/ 10 ноября 2009

Люди продолжают рекомендовать File :: Find, но другая часть, которая облегчает это, - мой File :: Find :: Closures , который предоставляет вам удобные функции:

 use File::Find;
 use File::Find::Closures qw( find_by_regex );

 my( $wanted, $reporter ) = find_by_regex( qr/^\d+\.\z/ );

 find( $wanted, @directories_to_search );

 my @files = $reporter->();

Вам даже не нужно использовать File::Find::Closures. Я написал модуль для того, чтобы вы могли извлечь подпрограмму, которую вы хотели, и вставить ее в свой собственный код, возможно, подправив его, чтобы получить то, что вам нужно.

2 голосов
/ 10 ноября 2009

Как уже отмечали другие, используйте File :: Find :

#!/usr/bin/perl

use strict;
use warnings;

use File::Find;

find(\&find_emails => '/var/spool');

sub find_emails {
    return unless /\A[0-9]+[.]\z/;
    return unless -f $File::Find::name;

    process_an_email($File::Find::name);
    return;
}

sub process_an_email {
    my ($file) = @_;
    print "Processing '$file'\n";
}
2 голосов
/ 10 ноября 2009

Используйте File :: Find для обхода дерева каталогов.

1 голос
/ 10 ноября 2009

Для фиксированного уровня каталогов иногда проще использовать glob , чем File :: Find:

while (my $file = </var/spool/[a-z]/user/*/*>) {
  print "Processing $file\n";
}
0 голосов
/ 10 ноября 2009

Попробуйте это:

sub browse($);

sub browse($)
{    
    my $path = $_[0];

    #append a / if missing
    if($path !~ /\/$/)
    {
        $path .= '/';
    }

    #loop through the files contained in the directory
    for my $eachFile (glob($path.'*')) 
    {

        #if the file is a directory
        if(-d $eachFile) 
        {
            #browse directory recursively
            browse($eachFile);
        } 
        else 
        {
           # your file processing here
        }
    }   
}#browse
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...