Cockneyphil has asked for the wisdom of the Perl Monks concerning the following question:

hi, could I use grep to add all the filenames of more than 1 dir into a single sorted array

Replies are listed 'Best First'.
Re: multiple dir. grep
by sh1tn (Priest) on Apr 06, 2005 at 12:59 UTC
    You mean recursion?
    use File::Find; my @dirs; find( sub { -d and push @dirs, $File::Find::name }, @ARGV ); print $_,$/ for @dirs;


Re: multiple dir. grep
by Roy Johnson (Monsignor) on Apr 06, 2005 at 13:20 UTC
    Something like
    @files = sort grep -f, map {opendir DIR, $_; readdir DIR} @dirlist;
    ? That's a little quick and dirty, since I don't closedir at all, and I don't check the return value of opendir. But it is kind of slick.

    If perl had an operator (call it <,) that would execute both sides (left-to-right) and return the left side, then I could neatly do the map as

    map { opendir DIR, $_; readdir DIR <, closedir DIR }
    I think that would come in handy reasonably often.

    Caution: Contents may have been coded under pressure.
      That's a little quick and dirty, since I don't closedir at all,

      Use a lexical dirhandle and perl will close it for you.

      perl -le"print for sort grep!/^\.\.?/, map{ opendir my($DIR), $_; rea +ddir $DIR } map glob, @ARGV" ./*

      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      Lingua non convalesco, consenesco et abolesco.
      Rule 1 has a caveat! -- Who broke the cabal?

      That's what the ol'

      select((select FH, $|=1)[0]);
      business is all about, so you could do
      map { open DIR, $_; @{ ( [ readdir DIR ], close DIR )[ 0 ] } } @dirli +st;
      Hmmm... Not exactly perspicuous.

      the lowliest monk

Re: multiple dir. grep
by tbone1 (Monsignor) on Apr 06, 2005 at 13:11 UTC
      hi, could I use grep to add all the filenames of more than 1 dir into a single sorted array

    Yes.

    (LAUGHS AT OWN JOKE)

    Oh, man, I really need a life.

    *ahem* Okay, this probably can be done if you can provide grep with a list of the directories (with globbing for the files in those directories). It requires a bit of programming, though, more than a one-line command.

    However, as has been mentioned previously in this thread, you're probably better off using sort instead. You'd probably need to use it anyway in the grep solution, so I'd recommend that approach.

    --
    tbone1, YAPS (Yet Another Perl Schlub)
    And remember, if he succeeds, so what.
    - Chick McGee

Re: multiple dir. grep
by tlm (Prior) on Apr 06, 2005 at 12:50 UTC

    Why would you need grep? Why not just use sort? The only use for grep I can envision for this problem is if you wanted to remove duplicates. Is that what you're asking?

    the lowliest monk

      note: I am fairly new to perl I have 2 dirs one contains files with sequential filenames ( 12345.dat, 12346.dat, 12347.dat etc..) the other contains similar filenames but with an alpha prefix (A23456.dat, F23457.dat, S23458.dat etc..) I need to create a list that contains the filenames of both dirs -with the newest filenames (higest sequential number regardless of prefix) from both at the top the code i am using (at the moment) for generating my list is:
      opendir THEDIR, "$dirpath" || die "cant open $dirpath !"; @allfiles = grep /^(?:158|159)/,readdir THEDIR; closedir THEDIR; foreach $file (sort { ($b) cmp ($a) } @allfiles) { print "$file\n";}
      please don't laugh..it took me a LONG time to get that to work. As you can see to make it all go a bit faster i have limited the list to only filenames that start with either 158 or 159. What I need to do is somehow get the contents of the other dir into this list whilst still keeping the newest filenames at the top. ps I'm not asking for a complete script just a few pointers as to how to go about doing it.

        It's quicker to code it than to explain it:

        use strict; my @dirs = qw(dir1 dir2 dir3); my @files; for my $dir ( @dirs ) { opendir my $dh, $dir or die "opendir failed: $dir ($!)\n"; push @files, grep -f $_, readdir $dh; } my @sorted = map $_->[ 0 ], sort { $b->[ 1 ] <=> $a->[ 1 ] } map [ $_, (/(\d+)/)[ 0 ] ], @files; __END__

        the lowliest monk