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

Is it possible to get the last lexical entry in a directory that contains only files (no subdirs) without reading the entire dir into an array, sorting it and poping the last entry off? Essentially the last listing of an 'ls' (this is linux only).

And a related question: Will readdir() always return a lexically sorted list?

Thanks.
  • Comment on find the last lexical entry in a dir without using @ls=readdir

Replies are listed 'Best First'.
Re: find the last lexical entry in a dir without using @ls=readdir
by thor (Priest) on Jan 10, 2005 at 00:38 UTC
    Sure. This method applies to any list, not just readdir.
    my $max; while( my $file = readdir(DIR) ) { $max = $file if $file gt $max; } print $max;
    Note: I used "unless" and "gt" rather than "if" and "le" because everything compares greater than undef, whereas nothing compares less than undef. If you want to use the latter instead of the former, you'll have to do a priming read (i.e. $min = readdir();) before the while loop.

    thor

    Feel the white light, the light within
    Be your own disciple, fan the sparks of will
    For all of us waiting, your kingdom will come

    Update: changed code to fix a logic error. Now finds max instead of min.
•Re: find the last lexical entry in a dir without using @ls=readdir
by merlyn (Sage) on Jan 10, 2005 at 00:57 UTC
    Will readdir() always return a lexically sorted list?
    I didn't know that it ever did! At least in Unix, it's the unsorted "directory" order, which is more or less random after files have been deleted and added to a given directory.

    -- Randal L. Schwartz, Perl hacker
    Be sure to read my standard disclaimer if this is a reply.

Re: find the last lexical entry in a dir without using @ls=readdir
by duff (Parson) on Jan 10, 2005 at 00:50 UTC

    I don't know if readdir will always return a sorted list, but I wouldn't rely on it. (I imagine that the list is in whatever order the entries are in the structure that holds the directory information which is certainly not sorted).

    Also, I don't know if your aversion to your method is because of the sorting or just reading the whole list of files into memory, but if you can live with all of the files in memory, you can use a simple for loop or List::Util's maxstr routine.

Re: find the last lexical entry in a dir without using @ls=readdir
by manywele (Initiate) on Jan 10, 2005 at 01:22 UTC
    Thanks for the answers. I didn't know gt worked that way on strings but I think you mean
    my $max while ( my $file = readdir(DIR) ) { $max = $file if $file gt $max; } print $max;
    And yes, I wanted to avoid reading tens of thousands of lines into memory just to get to the last entry. It seemed such a waste.

    As for the related question, the reason I asked is because I made a test dir, created new files in there in no particular order and readdir() returned a sorted list. Curious. Just checked with /usr/bin though and it is mostly but not entirely sorted.
Re: find the last lexical entry in a dir without using @ls=readdir
by BUU (Prior) on Jan 10, 2005 at 05:25 UTC
    Regarding 'lexical', you keep using that word. I do not think it means what you think it means.
      You are correct. s/lexical/alphanumeric/g