views:

273

answers:

7

I have a directory /var/spool and inside that, directories named

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

And inside each "letter directory", a directory called "user" and inside this, many directories called auser1 auser2 auser3 auser4 auser5 ...

Every user directory contains mail messages and the file names have the following format: 2. 3. 4. 5. etc.

How can I list the email files for every user in every directory in the following way:

    /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.

etc.

I need that files and then open every single file for modify the header and body. This part I already have, but I need the first part.

I am trying this:

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

But does not work the way I need it.

+3  A: 

You can use File::Find.

ghostdog74
+2  A: 

Use File::Find to traverse a directory tree.

Space
A: 

Try this:

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
Abdel Olakara
Hi, i've tried what did.. what I getting this error...main::browse() called too early to check prototype at -------sub browse($) {my $dir = $_[0];#append a / if missing if($path !~ /\/$/) { $path .= '/'; }if($dir !~ /\/$/) { $dir .= '/'; }#loop through the files contained in the directory ifor my $eachFile (glob($path.'*')) {for my $eachFile (glob($dir.'*')) {#if the file is a directoryif(-d $eachFile){ #browse directory recursively browse($eachFile);}else{ print $eachFile;}}}#browse-------Sorry, but.. what i am doing wrong?
Michael Fernandez
Let me guess: C is your favorite language?
innaM
Don't use prototypes. Don't re-invent the wheel.
Sinan Ünür
+1  A: 

As others have noted, use 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";
}
Sinan Ünür
Thanks a lot for the Help!!!!Thats worked great...So... now:, with...print $File::Find::name, "\n";I got what i need... is there a way to send that to a variable one per line in order to work with each single file modifying the messages?Thanks...Michael.-
Michael Fernandez
Cool!!!, thanks!!!! so much!Michael.-
Michael Fernandez
@Michael Fernandez: If a post answers your question, you mark it as accepted. That is appreciated much more than the multiple exclamation points.
Sinan Ünür
A: 

Thanks a lot for the Help!!!!

Thats worked great...

So... now:, with...

print $File::Find::name, "\n";

I got what i need... is there a way to send that to a variable one per line in order to work with each single file modifying the messages?

Thanks...

Michael.-

Michael Fernandez
+1 Spam is "an overtly commercial promotion". This is not spam.
Andomar
Sinan Ünür
Since this is not an answer, it should be asked as a separate question. Alternatively, you could edit the original question you posted here.
Bill the Lizard
Common! This is an answer by a NEW USER. It's worded in a nice and friendly way. The right action here is to point him in the right direction, instead of unexplained downvotes and spam flags.
Andomar
A: 

For a fixed level of directories, sometimes it's easier to use glob than File::Find:

while (my $file = </var/spool/[a-z]/user/*/*>) {
  print "Processing $file\n";
}
runrig
+2  A: 

People keep recommending File::Find, but the other piece that makes it easy is my File::Find::Closures, which provides the convenience functions for you:

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

You don't even need to use File::Find::Closures. I wrote the module so that you could lift out the subroutine you wanted and paste it into your own code, perhaps tweaking it to get what you needed.

brian d foy
Excellent, did not know about `File::Find::Closures`.
Sinan Ünür