Ellen
Ellen

Reputation: 17

Read newline delimited file in Perl

I am trying to read a newline-delimited file into an array in Perl. I do NOT want the newlines to be part of the array, because the elements are filenames to read later. That is, each element should be "foo" and not "foo\n". I have done this successfully in the past using the methods advocated in Stack Overflow question Read a file into an array using Perl and Newline Delimited Input.

My code is:

open(IN, "< test") or die ("Couldn't open");
@arr = <IN>;
print("$arr[0] $arr[1]")

And my file 'test' is:

a
b
c
d
e

My expected output would be:

a b

My actual output is:

a
 b

I really don't see what I'm doing wrong. How do I read these files into arrays?

Upvotes: 0

Views: 3412

Answers (3)

shawnhcorey
shawnhcorey

Reputation: 3601

  • Put the file path in its own variable so that it can be easily changed.
  • Use the 3-argument open.
  • Test all opens, prints, and closes for success, and if not, print the error and the file name.

Try:

#!/usr/bin/env perl

use strict;
use warnings;

# --------------------------------------

use charnames qw( :full :short   );
use English   qw( -no_match_vars );  # Avoids regex performance penalty

# conditional compile DEBUGging statements
# See http://lookatperl.blogspot.ca/2013/07/a-look-at-conditional-compiling-of.html
use constant DEBUG => $ENV{DEBUG};

# --------------------------------------

# put file path in a variable so it can be easily changed
my $file = 'test';

open my $in_fh, '<', $file or die "could not open $file: $OS_ERROR\n";
chomp( my @arr = <$in_fh> );
close $in_fh or die "could not close $file: $OS_ERROR\n";

print "@arr[ 0 .. 1 ]\n";

Upvotes: 1

Sinan &#220;n&#252;r
Sinan &#220;n&#252;r

Reputation: 118128

A less verbose option is to use File::Slurp::read_file

my $array_ref = read_file 'test', chomp => 1, array_ref => 1;

if, and only if, you need to save the list of file names anyway.

Otherwise,

my $filename = 'test';
open (my $fh, "<", $filename) or die "Cannot open '$filename': $!";

while (my $next_file = <$fh>) {
  chomp $next_file;
  do_something($next_file);
}

close ($fh);

would save memory by not having to keep the list of files around.

Also, you might be better off using $next_file =~ s/\s+\z// rather than chomp unless your use case really requires allowing trailing whitespace in file names.

Upvotes: 0

squiguy
squiguy

Reputation: 33370

Here is how I generically read from files.

open (my $in, "<", "test") or die $!;
my @arr;

while (my $line = <$in>) {
  chomp $line;
  push @arr, $line;
}

close ($in);

chomp will remove newlines from the line read. You should also use the three-argument version of open.

Upvotes: 4

Related Questions