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

Hi everyone, I've created a while loop where I print text in a txt file when a condition is true. There's just a little problem. When I run the perl script it prints the output to the file when the loop has finished. It should print it out directly.
open(LIST,$list); open(VULNFILE, ">>output.txt"); while ($d = <LIST>) { chomp ($d); if($d =~ /OK/) { print VULNFILE "OK\n"; } } close(LIST); close(VULNFILE);

Replies are listed 'Best First'.
Re: Print in TXT (while loop)
by ikegami (Pope) on Jul 24, 2008 at 23:03 UTC

    I/O is buffered by default. The output is written to the file when the (4KB) buffer fills up, not just when the file handle is closed.

    Buffering can be turned off on a per handle basis.

    use IO::Handle qw( ); VULNFILE->autoflush(1);

    By the way, do you have a reason to use global variables and 2-arg open?

    use strict; use warnings; use IO::Handle qw( ); my $list_qfn = '...'; my $vuln_qfn = '...'; open(my $list_fh, '<', $list_qfn) or die("Unable to open list file \"$list_qfn\": $!\n); open(my $vuln_fh, '>>', $vuln_qfn) or die("Unable to append to vulnerability file \"$vuln_qfn\": $!\n) +; # Disable buffering. $vuln_fh->autoflush(1); while (<$list_fh>) { chomp; if (/OK/) { print $vuln_fh "OK\n"; } } close($list_fh); close($vuln_fh);
Re: Print in TXT (while loop)
by gloryhack (Deacon) on Jul 24, 2008 at 23:08 UTC
Re: Print in TXT (while loop)
by marto9 (Beadle) on Jul 25, 2008 at 08:41 UTC
    Thx for the replies. Ikegami gave me an easy solution. But isn't it easier to just use a for loop then? Or does it have disadvantages too?

      "I have a buffering problem, so I'll use 'for' instead of 'while'." I don't see the relation or the logic in that.

      If it's an independent question, then not only is it not easier (while (<$list_fh>) vs for (<$list_fh>) are equally easy to type), the for version needlessly uses more memory. for (<$list_fh>) causes the entire file to be read into memory before the loop starts whereas while (<$list_fh>) (short for while (defined($_ = <$list_fh>))) reads one line at a time.

      Like this ...

      for ( ; my $in = <$fh> ; ) { ... } # or ... for ( ;; ) { last if eof $fh; my $in = <$fh>; ... }

      ... ? The first case is very much like while with the additions of empty initialization & increment statements both of which happened to be covered by the loop end condition. So all you gain is obfuscation with for loop in this case.

      No, it isn't, and it has disadvantages (reads whole file into memory at once)