Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

Show count before data output

by Anonymous Monk
on Jun 23, 2003 at 12:34 UTC ( #268132=perlquestion: print w/ replies, xml ) Need Help??
Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

I have a script that outputs data and the total count. Please advise how I can get the count to appear first before the data output. Right now the count comes up after the data output on the very last page. I need the count to show BEFORE the data output. Is that possible??
use File::Find; my $ct = 0; sub fetcher { if( $_ =~ /\.html?$/) { my $name = $File::Find::name; open ( F, $name ) or die "$!: $name\n"; while( $line = <F> ) { for $i ($line =~ /stuffhere)/gi ) { print "$i\n"; $ct++; } } close F; } } #print "\n\nTotal Count = $ct\n\n"; also tried putting count here and + it still prints count after data find( \&fetcher, "/directory" ); print "\n\nTotal Count = $ct\n\n";

Comment on Show count before data output
Download Code
Re: Show count before data output
by particle (Vicar) on Jun 23, 2003 at 12:44 UTC

    it looks like you need to put your data into memory when you find it, then print it later. right now, you print it inside the fetcher subroutine, where it's impossible to have a final count also. try something like:

    ## ... my @file_data; sub fetcher { ## ... while ... for ... { ## ... push @file_data, $i; $ct++; } } ## print here...

    ~Particle *accelerates*

Re: Show count before data output
by Tomte (Priest) on Jun 23, 2003 at 12:46 UTC

    Since you are printing the data inside of the while-loop, it's printed before the count-value. You told the programm to do.
    A solution is to gather the lines in an array, and print them after the while-loop, (of course unless you are reading more lines than fit into memory):

    use File::Find; sub fetcher { my($ct, @data) = (0,()); if( $_ =~ /\.html?$/) { my $name = $File::Find::name; open ( F, $name ) or die "$!: $name\n"; #while( $line = <F> ) # { # for $i ($line =~ /stuffhere)/gi ) { # push(@data, "$i\n"); # gather the lines # $ct++; # } #} # since there is no requirement the lines need to match # why not local $/ = undef; @data = <F>; close F; } return($ct,\@data); } my ($ct, $data) = find( \&fetcher, "/directory" ); print @$data; print "\n\nTotal Count = $ct\n\n";
    should do it. Note that I modified your loop, but provided a more proper solution below it.

    Since you are reading in html-files, I wonder if some CPAN-Module might be of interest to you.

    regards,
    tomte

    Update:Modified the code to slurp the file in.

    Update II:fixed the CPAN-link.


    Hlade's Law:

    If you have a difficult task, give it to a lazy person --
    they will find an easier way to do it.

      Thanks, I tried as you suggested and got this message:
      Use of uninitialized value at fet7a.pl line 28. Total Count =
      Here is what I have:
      use File::Find; sub fetcher { my($ct, @data) = (0,()); if( $_ =~ /\.html?$/) { my $name = $File::Find::name; open ( F, $name ) or die "$!: $name\n"; while( $line = <F> ) { for $i ($line =~ /stuff/gi ) { push(@data, "$i\n"); # gather the lines $ct++; } } # since there is no requirement the lines need to match # why not local $/ = undef; @data = <F>; close F; } return($ct,\@data); } my ($ct, $data) = find( \&fetcher, "/directoryHere" ); print @$data; print "\n\nTotal Count = $ct\n\n";

        I should read posts more carefuly before answering, your use of File::Find was totaly unnoticed by me. You can't pass return values through the call of find, use a global variable instead, as you originaly did. Here a slightly modified version, that searches use lines in .pl files.

        use File::Find; my($ct, @data) = (0,()); sub fetcher { if( $_ =~ /\.pl?$/) { my $name = $File::Find::name; open ( F, $name ) or die "$!: $name\n"; my @lines = <F>; close(F); my @matches = grep(/^use/, @lines); push(@data, @matches); $ct += scalar(@matches); } } find( {wanted => \&fetcher, no_chdir => 1, }, "." ); print "\n\nTotal Count = $ct\n\n"; print @data; __END__ Total Count = 8 use strict; use WWW::Search::Tv::German::Tvtoday 1.02; use File::Find; use File::Basename; use HTML::TokeParser; use LWP::Simple; use LWP::Simple; use Net::POP3;
        Notice that I slurp the file and use grep to find the matches, I think it looks more like perl this way.

        And by the way: I would realy like to know, for what purpose you wrote this code, as it seems to me, if you had posted that, someone could come up with a more proper solution, just a humble guess...

        Oh, and as a further note: proper, read: consistent, indenting of code is most welcome here ;-)

        regards,
        tomte


        Hlade's Law:

        If you have a difficult task, give it to a lazy person --
        they will find an easier way to do it.

Re: Show count before data output
by broquaint (Abbot) on Jun 23, 2003 at 12:46 UTC
    The lazy way would be to tie up STDOUT e.g
    use IO::Scalar; tie *STDOUT, 'IO::Scalar' => \my $stdout; find( \&fetcher, "/directory" ); untie *STDOUT; print "\n\nTotal Count = $ct\n\n"; print $stdout;
    Or you could change your code to build up the output then display the accumulated output after the total count. See. IO::Scalar for more info on the hack above.
    HTH

    _________
    broquaint

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://268132]
Approved by particle
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others having an uproarious good time at the Monastery: (10)
As of 2014-07-28 19:27 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My favorite superfluous repetitious redundant duplicative phrase is:









    Results (207 votes), past polls