Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation
 
PerlMonks  

Print contents of text file line by line

by TonyNY (Beadle)
on Jun 23, 2018 at 18:55 UTC ( #1217298=perlquestion: print w/replies, xml ) Need Help??

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

Hi,

How can I read the contents of a text file and print each line one by one?

I've tried the following but it only prints "something here" a whole bunch of times.

$filename='result.txt'; open( my $fh, '<', $filename ) or die "Can't open $filename: $!"; while ( my $line = <$fh> ) { print "something here $line[0]"; print "something here $line[1]"; print "something here $line[2]"; } close $fh;

Thanks

Replies are listed 'Best First'.
Re: Print contents of text file line by line
by AnomalousMonk (Archbishop) on Jun 23, 2018 at 20:23 UTC

    Further to stevieb's remarks++ about properly understanding the context in which the  $fh filehandle is read in the OPed while-loop, note that if you had enabled strict at the start of your code, the code would not even have compiled due to the absence of an explicit declaration of a  @line array before using it. ($line[n] accesses the  @line array). So (all code examples untested)

    use strict; $filename = 'result.txt'; open( my $fh, '<', $filename ) or die "Can't open '$filename': $!"; while ( my $line = <$fh> ) { print "something here $line[0]"; print "something here $line[1]"; print "something here $line[2]"; } close $fh;
    would have failed to compile and would have thrown an error message about the undeclared  @line array that might have pointed you in the right debugging direction.

    If a  @line array had, for some reason, been declared before the while-loop, there would have been no compile-time error, but the use of the warnings module would have produced a run-time warning (not an error | a fatal error) about the use of an uninitialized variable:

    use strict; use warnings; $filename = 'result.txt'; open( my $fh, '<', $filename ) or die "Can't open '$filename': $!"; my @line; while ( my $line = <$fh> ) { print "something here $line[0]"; print "something here $line[1]"; print "something here $line[2]"; } close $fh;
    The warning will have a source code line number associated with it which should aid in understanding the nature of the problem.

    Bottom line: If you're a novice Perl programmer, always enable warnings and strict. If you're not a novice Perl programmer, then always enable warnings and strict — unless you have a very good and clearly understood reason not to do so.

    Update: As hippo pointed out, we have Tutorials in the Monastery, and Use strict and warnings is a good one about strict (and warnings). See also the supplementary links at the end of the article.


    Give a man a fish:  <%-{-{-{-<

      Understood, thanks
Re: Print contents of text file line by line
by Laurent_R (Canon) on Jun 23, 2018 at 21:53 UTC
    Hi TonyNY,

    if you use this syntax:

    open( my $fh, '<', $filename ) or die "Can't open $filename: $!"; while ( my $line = <$fh> ) { # ... }
    what you get each time through the loop is one single line (a scalar variable, not an array).

    So you probably want to have something like this:

    open( my $fh, '<', $filename ) or die "Can't open $filename: $!"; while ( my $line = <$fh> ) { print "something here $line"; }
    Update: removed an extra closing curly bracket that I had left inadvertently at the end.
Re: Print contents of text file line by line
by Marshall (Canon) on Jun 23, 2018 at 22:03 UTC
    #!/usr/bin/perl use strict; use warnings; my $filename='result.txt'; open( my $fh, '<', $filename ) or die "Can't open $filename: $!"; while ( my $line = <$fh> ) { $line =~ s/\s*$//; # remove any line ending char(s) # this works on Windows, Unix and old Apple print "$line\n"; # print with line endings for this platform } close $fh;
    The substitution expression is to get rid of any combination of
    <line feed>,<carriage return>.<space> at end end of the line.

    Unix uses <LF> to separate lines.
    Windows uses <CR> then <LF> to separate lines. Old Apple uses <CR>.

    The print uses the line endings for the platform that you are using.

Re: Print contents of text file line by line
by hippo (Bishop) on Jun 23, 2018 at 22:33 UTC
      Thanks
Re: Print contents of text file line by line
by jbodoni (Monk) on Jun 24, 2018 at 14:27 UTC

    Here's one way to do it</p.

    #!/usr/bin/perl use strict;use warnings; print while ( <> );

    You'd run it by invoking the program name followed by the name of the text file: program.pl textfile.txt

Re: Print contents of text file line by line
by usemodperl (Beadle) on Jun 23, 2018 at 19:05 UTC

      That will slurp the entire file into memory all at once, which is almost always what isn't desired.

      Use the scalar, but do so in proper context. The OP is assuming that the return from each file handle read is an array, which it isn't. In a while() loop like the OP has, the file handle is read a line at a time, so the scalar holds everything up to end-of-line (including the newline character(s)). To use an array as you suggested would mean that you'd have to eliminate said while() loop.

      use warnings; use strict; open my $fh, '<', "file.txt" or die "can't open the flippin' flabergastin' file!: $!"; while (my $line = <$fh>){ chomp $line; print "something here $line\n"; }

      Note that if the while() block is very small, a well-known Perl idiom is to use the built-in special default variable:

      use warnings; use strict; open my $fh, '<', "file.txt" or die "can't open the flippin' flabergastin' file!: $!"; while (<$fh>){ chomp; print "something here $_\n"; }
      Edit: Wrongish answer deleted...

      Still wrongish, unfortunately, because it makes stevieb's previously pertinent reply seem incoherent. Please see How do I change/delete my post?. The Golden Rule: Don't destroy context.


      Give a man a fish:  <%-{-{-{-<

        Still wrongish, unfortunately, because it makes stevieb's previously pertinent reply seem incoherent.

        I see what you mean. Sorry about that, it was not my intent, stevieb was given credit after all. I put a reference to my mistake back in the node...

        STOP REINVENTING WHEELS, START BUILDING SPACE ROCKETS!CPAN 🐪
      Thanks modperl...I see my mistake in trying to print the elements of an array without first declaring the array...
        Unless you really want to print only selected lines of the file, you probably should use the line-by-line approach that you currently (unintentionally) wrote, and add a counter of the number of times this loop has executed, and end the loop after you have printed enough. This will work for any file regardless of size.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1217298]
Approved by haukex
Front-paged by haukex
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others meditating upon the Monastery: (6)
As of 2023-01-31 19:34 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?