Skip to content


Subversion checkout URL

You can clone with
Download ZIP
Fetching contributors…
Cannot retrieve contributors at this time
140 lines (91 sloc) 4.05 KB

Files and directories

Read files easily with open and the <> operator

Opening and reading files with Perl is simple. Here's how to open a file, read it line-by-line, check it for text matching a regular expression, and print the lines that match.

    open( my $fh, '<', $filename ) or die "Can't open $filename: $!";
    while ( my $line = <$fh> ) {
        if ( $line =~ /wanted text/ ) {
            print $line;
    close $fh;

Always check the return code from open() for truthiness. If there's a failure, the result is in $!.

Remove trailing linefeeds with chomp

Lines read from a file have their trailing linefeed still attached. If you have a text file where the first line is


"Aaron", is actually "Aaron\n", six characters. This code will fail:

    my $line = <$fh>;
    if ( $line eq 'Aaron' ) {
        # won't reach here, because it's really "Aaron\n";

To remove the "\n", and any other trailing whitespace, call chomp.

    my $line = <$fh>;
    chomp $line;

Now $line is five characters long.

Change your line delimiter with $/

It's possible to change your input record separator, $/. It's only set to "\n" by default.

Set $/ to read a paragraph at a time. Set $/ to undef to read the entire file at once. See perlvar for details.

Slurp an entire file at once

Typically you'll see novices read a file using one of thse two methods:

    open (FILE,$filename) || die "Cannot open '$filename': $!";
    undef $/;
    my $file_as_string = <FILE>;


    open (FILE,$filename) || die "Cannot open '$filename': $!";
    my $file_as_string = join '', <FILE>;

Of those two, choose the former. The second one reads all the lines into an array, and then glomps together a big string. The first one just reads into a string, without creating the intervening list of lines.

The best way yet is like so:

    my $file_as_string = do {
        open( my $fh, $filename ) or die "Can't open $filename: $!";
        local $/ = undef;

The do() block returns the last value evaluated in the block. This method localizes the $/ so that it gets set back outside the scope of the block. Without localizing $/, it retains the value being set to it and another piece of code might not be expecting it to have been set to undef.

Here's another way:

    use File::Slurp qw( read_file );
    my $file_as_string = read_file( $filename );

File::Slurp is a handy module for reading and writing a file at a time, and it does magic fast processing on the back end.

Get lists of files with glob()

Use standard shell globbing patterns to get a list of files.

    my @files = glob( "*" );

Pass them through grep to do quick filtering. For example, to get files and not directories:

    my @files = grep { -f } glob( "*" );

Use unlink to remove a file

The Perl built-in delete deletes elements from a hash, not files from the filesystem.

    my %stats;

    $stats{filename} = 'foo.txt';

    unlink $stats{filename}; # RIGHT: Removes "foo.txt" from the filesystem

    delete $stats{filename}; # WRONG: Removes the "filename" element from %stats

The term "unlink" comes from the Unix idea of removing a link to the file from the directory nodes.

Use Unix-style directories under Windows

Even though Unix uses paths like /usr/local/bin and Windows uses C:\foo\bar\bat, you can still use forward slashes in your filenames.

    my $filename = 'C:/foo/bar/bat';
    open( my $fh, '<', $filename ) or die "Can't open $filename: $!";

In this case, Perl magically changes the C:/foo/bar/bat to C:\foo\bar\bat before opening the file. This also prevents the problem where an unquoted backslash screws up a filename, as in:

    my $filename = "C:\tmp";

In this case, $filename contains five characters: 'C', ':', a tab character, 'm' and 'p'. Instead, it should have been written as one of:

    my $filename = 'C:\tmp';
    my $filename = "C:\\tmp";

Or, you can let Perl take care of it for you with:

    my $filename = 'C:/tmp';


Hey! The above document had some coding errors, which are explained below:

Around line 47:

Deleting unknown formatting code P<>

Jump to Line
Something went wrong with that request. Please try again.