20

Adding a standard Perl file open function to each script I have is a bit annoying:

sub openfile{
    (my $filename) = @_;
    open FILE,"$filename" or die $!;
    my @lines = <FILE>;
    return @lines;
}

and I can create a Perl module to do this, but this is so simple I'm sure there should be one out there already.

I'm trying to find a way to read a text file into an array, and I cant seem to find a Perl module out there that can do this simple task... maybe I'm looking too hard and it already came with the standard 5.10 install.

Optimally I believe it would look something like this:

my @lines = Module::File::Read("c:\some\folder\structure\file.txt");
2
  • I would highly recommend Text::CSV::Slurp for anyone wanting to work with CSV files. This module worked much better than the two or three others I tried. The next best was CSV::Slurp::Simple or something along those lines, though not as robust as Text::CSV::Slurp. Commented Apr 28, 2009 at 19:11
  • 2
    Use 3 arg form of open() p3rl.org/open Commented Jul 22, 2009 at 16:41

8 Answers 8

28

You have several options, the classic do method:

my @array = do {
    open my $fh, "<", $filename
        or die "could not open $filename: $!";
    <$fh>;
};

The IO::All method:

use IO::All;

my @array = io($filename)->slurp;

The File::Slurp method:

use File::Slurp;

my @array = read_file($filename);

And probably many more, after all TIMTOWTDI.

Sign up to request clarification or add additional context in comments.

2 Comments

Definately like the File::Slurp method. Thank you so much!
Note that File::Slurp predates the Perl IO layers, and therefore won't honor the PERL_UNICODE/perl -C settings which may be surprising when you're trying to write Perl scripts with proper Unicode support. Path::Tiny might be an alternative with better Unicode support.
16

that is the famous "slurp mode":

  my @lines = <FILEHANDLE> ;

you may also see Perl Slurp Ease

2 Comments

"slurp mode" is more commonly used to mean reading the whole file into a single scalar, by setting the record separator $/ to undef.
I've seen both array and scalar context described as slurp mode, but I've seen the array style used more often.
15

I think this is what you are looking for

File::Slurp

Comments

7

Also have a look at Perl6::Slurp which implements the Perl6 version of slurp and is recommended in the "Perl Best Practices" book.

Some examples....

my @lines         = slurp 'filename';
my @lines_chomped = slurp 'filename', { chomp => 1 };
my @lines_utf8    = slurp 'filename', { utf8  => 1 };

Comments

6

You might also want to consider using Tie::File, particularly if you are reading larger files and don't want to read the entire file into memory. It's a core module. Also, please refer to perlfaq5.

Comments

4

You've gotten the general techniques, but I want to put in that Perl sort of discourages you from doing that because it's very often the case that you can do the same thing you're doing one-line-at-a-time, which is inherently far more efficient.

1 Comment

A good point, especially when reading into an array. Arrays imply sequential processing by lines (or records if $/ is being used) which is often better done one-item-at-a-time. However, there are cases where it is appropriate to slurp.
2

For quick and dirty, I rather like the simplicity of mucking with @ARGV.

# Ysth is right, it doesn't automatically die; I need another line.
use 5.010;
use strict;
my @rows = do { 
    use warnings FATAL => 'inplace'; # oddly enough, this is the one. ??
    @ARGV='/a/file/somewhere';
    <>;
};
say q(Not gettin' here.);

If perl* cannot open the file, it automatically dies.


* - the executable, so please don't capitalize.

4 Comments

I didn't know that Perl wasn't an abbreviation! Thanks for the heads up.
Sorry, the note was not for you but for the notorious Capital-P gang. They'll break into your post and capitalize your P's when you specifically meant the executable. The language gets a capital-P--only. There's no anagram, though.
I thought the capital-P gang was careful to distinguish.
No, perl does not automatically die - it just warns and continues.
2

I would recommend an object oriented approach that does not requires modules outside the CORE distribution and will work anywhere:

use strict;
use warnings;
use IO::File;
my $fh = IO::File->new("< $file");

foreach ($fh->getlines) {
    do_something($_);
}
$fh->close

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.