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

UPDATE 1-8-03 - I have posted the finished version to the end of this post so others may happen upon it when in need.

Ahhh...more intro Perl homework goodness. :)

So far, with your kind assistance, I have written;

#!/usr/bin/perl use warnings; use strict; open (OUTFILE, ">>midterm.html"); my $dir = "/Users/ctp/PERL_work"; my @dirs; my @files; # read all entries from dir and skip '.' and '..' directories opendir (DIRHANDLE, $dir) or die "can't open $dir: $!"; my @list=grep !/^\.\.?\z/, readdir DIRHANDLE; print (OUTFILE "<HTML>\n<HEAD></HEAD>\n<BODY>\n"); # now we sort the list on directory basis foreach my $file (sort {-d "$dir/$b" <=> -d "$dir/$a"} @list) { print "<B>$file</B><BR>\n" if -d "$dir/$file"; print "$file<BR>\n" if -T "$dir/$file"; } closedir (DIRHANDLE); print @dirs; print (OUTFILE "</BODY>\n</HTML>\n"); close (OUTFILE);
Inside the foreach loop I have two print statements. I want that output to also go to my OUTFILE. I have tried printing them to the filehandle directly, I have tried pushing the output into an array, I have tried a few other things, all of which produced syntax errors. None of my books have any examples that are even close...not that I can find anyway.

BTW - In my previous (part one) query an anonymous monk suggested perldoc -f open and perldoc-f select. After poring over perldoc -f in three books I'm still; not getting how to make use of that one...not that that's what I want to do or not do necessarily, but it was brought up

Thanks again!

PS - as always, since this is homework, if you know of a good example please direct me to it (print or online) so I can read up!

--begin final version--
#!/usr/bin/perl use warnings; use strict; #open file for output open (OUTFILE, ">>dircontents.html"); #declare $dir variable and set our directory my $dir = "/Users/ctp/PERL_work"; # create dir handle read all entries from directory opendir (DIRHANDLE, $dir) or die "can't open $dir: $!"; #skip "." and ".." directories my @list=grep !/^\.\.?\z/, readdir DIRHANDLE; #print HTML header to our file print (OUTFILE "<HTML>\n<HEAD></HEAD>\n<BODY>\n"); # sort the list on directory basis and close dir handle foreach my $file (sort {-d "$dir/$b" <=> -d "$dir/$a"} @list) { print (OUTFILE "<B>$file</B><BR>\n") if -d "$dir/$file"; print (OUTFILE "$file<BR>\n") if -T "$dir/$file"; } closedir (DIRHANDLE); #print HTML footer to file and close filehandle print (OUTFILE "</BODY>\n</HTML>\n"); close (OUTFILE);

Replies are listed 'Best First'.
Re: reading files and directories, part two
by davido (Cardinal) on Jan 08, 2004 at 07:46 UTC
    I read your question as asking, "How do I print to STDOUT and OUTFILE simultaneously?" This response answers what I think you're asking.

    Though it may be overkill for a short script, there is always the IO::Tee module on CPAN, which allows you to write to multiple filehandles with a single print call.

    From the POD, here is an example:

    use IO::Tee; $tee = IO::Tee->new($handle1, $handle2); print $tee "foo", "bar";

    So the idea would be to call IO::Tee->new(...) with OUTFILE and STDOUT as its arguments. To do that, I believe you would do it like this:

    $tee = IO::Tee->new(\*STDOUT, \*OUTFILE); print $tee "Your data here" if .....

    Or you could try a "roll your own" solution by using the aliasing characteristic of a for loop to multiplex the filehandles for you, like this:

    use strict; use warnings; open my $fh, ">test.out" or die "Can't open outfile."; print $_ "Test string.\n" for \*STDOUT, $fh; close $fh;

    Hope this helps!


    Dave

Re: reading files and directories, part two
by chimni (Pilgrim) on Jan 08, 2004 at 07:52 UTC

    Davido's right.another way could be:
    On a unix system
    perl -e 'print "Hello world\n";' | tee output.txt
    If you want ALL the oitput of your script to go to both a logfile and the screen
    you could just run your script like this
    perl scriptname | tee filename.
    HTH
Re: reading files and directories, part two
by Hofmator (Curate) on Jan 08, 2004 at 13:18 UTC

    If you just want to print to OUTFILE and not print to stdout as well (davido has answered that part), just replicate your other print statements, like this:

    print (OUTFILE "<B>$file</B><BR>\n") if -d "$dir/$file";

    And perldoc -f open is something you have to enter at a command line prompt which gives you documentation on the perl function 'open' - in case this was the problem and not the documentation of the 'open' function itself.

    -- Hofmator

      AY YI YI!!!! I wrote that very line and I just had the closing parenthesis in the wrong spot, but now that I look at it it's a total forehead slapper. Thanks for the clarification!

      I do just want to print to the file, not STDOUT...sorry about not being clearer in the OP. I'll hang onto that other code snippet though because I know that will come up sometime.

      On the command line solution idea - that's *exactly* what I would have done in the real world, but this being homework I knew all my functionality had to be in the script.

      On the perldoc thing, that's the sense I got, but I guess I was reading more into it than I should have. I was up well past my expiry date while working on it the last 2 nights...Ah well......

        Btw, you don't need these parentheses there, print OUTFILE "<B>$file</B><BR>\n" if -d "$dir/$file"; works just fine.

        I was just sticking to your 'original' style in my answer, though for me the 2nd way reads better. But consistency is more important, so either change every usage of print or leave it as it is.

        -- Hofmator