Main Navigation

Content

Files and Directories Handling in Perl

Learn Perl Now!
And get a job doing Perl.

Perl has strong support for handling files and directories, which are the bread-and-butter of dealing with the disk and the filesystem. Many modules on CPAN (= the Comprehensive Perl Archive Network) aim to facilitate the task even further.

Table of Contents

The Basics

For the basics, read about the open function (on perlopentut or on recommended books or tutorials) as well as other built-ins such as opendir, readdir, closedir, mkdir. There are also many UNIX-oriented file-system-builtins listed on perlfunc which may prove of utility.

Modules

Useful modules for files and directories handling are:

Directory Traversal

The built-in module for traversing a directory tree in Perl is File::Find, but it has some severe limitations in interface and use. Some better alternatives are:

Examples

These are a set of examples for manipulating files and directories using Perl. Each will be shown in several versions including ones using IO-All, ones using core modules, and if relevant ones from the command line.

Reading a file line by line

#!/usr/bin/perl

use strict;
use warnings;

use IO::All;

my $filename_to_read = 'my-file.txt';

my $fh = io->file($filename_to_read);
while (my $line = $fh->chomp->getline())
{
    # Do something with $line.
}


#!/usr/bin/perl

use strict;
use warnings;

use autodie;

my $filename_to_read = 'my-file.txt';

open my $fh, '<', $filename_to_read;
while (my $line = <$fh>)
{
    chomp($line);

    # Do something with $line.
}
close($fh);


Copying a file

#!/usr/bin/perl

use strict;
use warnings;

use IO::All;

my ($source_filename, $dest_filename) = @_;
io->file($source_filename) > io->file($dest_filename);


#!/usr/bin/perl

use strict;
use warnings;

use File::Copy qw(copy);

my ($source_filename, $dest_filename) = @_;

copy($source_filename, $dest_filename);


Overwriting a file with text

#!/usr/bin/perl

use strict;
use warnings;

use IO::All;

io->file("output.txt")->utf8->print("Hello World!\n");


#!/usr/bin/perl

use strict;
use warnings;

use autodie;

open my $out, '>:encoding(utf8)', "output.txt";
print {$out} "Hello World!\n";
close($out);


Processing the Lines of a File

#!/usr/bin/perl

use strict;
use warnings;

use File::Slurp;

my @filenames = @ARGV;

foreach my $fn (@filenames)
{
    edit_file_lines sub { s/\bFrom\b/To/g }, $fn;
}


#!/usr/bin/perl

use strict;
use warnings;

use autodie;
use File::Temp ( qw(tempfile) );

my @filenames = @ARGV;

foreach my $fn (@filenames)
{
    open my $in, '<', $fn;
    my ($tempout, $temp_fn) = tempfile();

    while (my $line = <$in>)
    {
        chomp($line);
        # Perform the operation here.
        $line =~ s/\bFrom\b/To/g;

        print {$tempout} "$new_line\n";
    }

    close($in);
    close($tempout);

    rename($temp_fn, $fn);
}


$ perl -i.bak -lp -e 's/\bFrom\b/To/g' *.txt

Reading an entire UTF-8 file into a big variable

#!/usr/bin/perl

use strict;
use warnings;

use IO::All;

my $string = io->file($my_filepath)->utf8->all;


#!/usr/bin/perl

use strict;
use warnings;

use autodie;

sub _utf8_slurp
{
    my $filename = shift;

    open my $in, '<:encoding(utf8)', $filename;

    local $/;
    my $contents = <$in>;

    close($in);

    return $contents;
}

my $file_contents = _utf8_slurp($my_filepath);


$ perl -i.bak -ln -0777 -C -ln -e 'Something with $_ here' "$my_utf8_filepath"

Appending to a File

#!/usr/bin/perl

use strict;
use warnings;

use IO::All;

my $string_to_append = "My new line\n";

$string_to_append >> io->file($my_file_path);


#!/usr/bin/perl

use strict;
use warnings;

use autodie;

my $string_to_append = "My new line\n";

{
    open my $out, '>>', $my_file_path;
    print {$out} $string_to_append;
    close($out);
}


Line count

#!/usr/bin/perl

use strict;
use warnings;

use IO::All;

sub count_lines
{
    my ($filename) = @_;

    my $fh = io->file($filename);

    my $count = 0;

    while (my $l = <$fh>)
    {
        $count++;
    }

    return $count;
}


#!/usr/bin/perl

use strict;
use warnings;

use autodie;

sub count_lines
{
    my ($filename) = @_;

    open my $fh, '<', $filename;

    my $count = 0;
    while (my $l = <$fh>)
    {
        $count++;
    }

    close($fh);

    return $count;
}


$ perl -lnE 'END{say "$ARGV has $. lines";}' /path/to/myfile.txt

Deleting a directory tree

#!/usr/bin/perl

use strict;
use warnings;

use IO::All;

io("./path-to-subdir")->rmtree();


#!/usr/bin/perl

use strict;
use warnings;

use File::Path qw(rmtree);

rmtree(["./path-to-subdir"], 1, 1);


Prepending to a File (While Slurping)

#!/usr/bin/perl

use strict;
use warnings;

use IO::All;

my $filename = 'foo.txt';
my $text_to_prepend = "[Text to Prepend]\n";

my $fh = io->file($filename);

$fh->print( $text_to_prepend . $fh->all() );


#!/usr/bin/perl

use strict;
use warnings;

my $filename = 'foo.txt';
my $text_to_prepend = "[Text to Prepend]\n";

open my $in_fh, '<', $filename
    or die "Could not open file '$filename' for reading! - $!";
my $contents = do { local $/; <$in_fh>;};
close($in_fh);

open my $out_fh, '>', $filename
    or die "Could not open file '$filename' for writing! - $!";
print {$out_fh} $text_to_prepend . $contents;
close($out_fh);


Share/Bookmark

Sidebar

Footer