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

I've got the part down now with removing certain elements from an array, and i've read around on other ways to the same thing, but what I am stuck with now is that the directory contents are read into an array the array is filtered of . .. and the scripts name. What then i need to do is have the remaining elements (or all of them if it should be done before filtering) sorted into two other arrays; @files @directories.

brainstorming I figured sorting according to if the element has a "." in it (index.html vs /protected)

Here's my code. Help if you can or point me to where i can read how to do it! :)
#!/usr/bin/perl -w print "Content-type: text/html\n\n"; opendir(DIR,"./") || die print "Couldn't open directory"; my @unsfiles = readdir(DIR); closedir(DIR); @files = sort(@unsfiles); my $filename = __FILE__; my @noshow = (".", "..", $filename); print <<html; <html> <body> <div style=\"{ border: solid 1 #003366; background: #F1F1F1; text-align: left; padding: 4px; width: 200px; }\"> html foreach $f (@files) { unless (grep /$f/, @noshow) { print "<a style=\"{font-size: 13px; color: #000000;\"} href=\"./rea +d_file.cgi?file=$f\">$f</a><br>\n"; } } print <<html2; </div> </body> </html> html2
I know people are telling me not to use die print "", but is there another way for the die error to print to the screen when viewed by an internet browser (IE) ? thanks all!

Replies are listed 'Best First'.
Re: more with directory contents
by Chmrr (Vicar) on Jan 14, 2002 at 17:33 UTC

    Here's how I'd do this. Do note the use of CGI.pm (this beast is now big enough to use it, and the HTML shortcuts will come in handy) as well as strict. I can't stress enough how useful strict is. If you havn't already, please do read all of use strict warnings and diagnostics or die.

    The generalization that directories do not contain periods is not particularly true. The true way to test is with the -d file test operator.

    Also, CGI::Carp will spew error messages to the browser, like you were looking for.

    Anyways, here's how I'd do it:

    #!/usr/bin/perl -w use strict; use CGI qw/:standard escape/; use CGI::Carp; my @noshow = (".", "..", __FILE__); my (@directories,@files); opendir(DIR,"./") or die "Couldn't open directory: $!"; for my $entry (sort readdir(DIR)) { next if grep {$_ eq $entry} @noshow; if (-d $entry) { push @directories, $entry; } else { push @files, $entry; } } closedir(DIR); print header, start_html, div({-style=>"border: solid 1 #003366; background: #F1F1F1; text-align: left; padding: 4px; width: 200px;"}, map {a({-style => "font-size: 13px; color: #000000;", -href => "./read_file.cgi?file=".escape($_)},$_) .br} @files), end_html;

    perl -pe '"I lo*`+$^X$\"$]!$/"=~m%(.*)%s;$_=$1;y^`+*^e v^#$&V"+@( NO CARRIER'

the second part
by erroneousBollock (Curate) on Jan 14, 2002 at 18:46 UTC
    To test whether some "file" is a directory, this logic will work:
    if (-d $filename) { print "directory\n"; } else { print "other\n"; }

    So if you have @filenames, you can filter it into @files and @dirs with this sub:
    sub filter_names { my ($nref,$fref,$dref) = @_; for (@$nref) { if (-d) { push @$dref, $_; } else { push @$fref, $_; } } }

    Call it like:
    filter_names(\@filenames,\@files,\@dirs);

    that ok?
    Update: Oops Chmrr said the same thing already... sorry.
Re: more with directory contents
by Marcello (Hermit) on Jan 14, 2002 at 17:43 UTC
    Hi, You can filter the ., .. and the scripts name out of the readdir by replacing
    my @unsfiles = readdir(DIR);
    with
    my $filename = __FILE__; my @unsfiles = grep(!/^(\.|$filename)/, readdir(DIR));
    provided that none of the other files in the directory start with a dot (.) or your scripts name.
    If all your files contain a dot, and the directories not, use the following greps to separate into files and directories:
    my @files = grep(/\./, @unsfiles); my @dirs = grep(!/\./, @unsfiles);
    Good luck!