- publishing free software manuals
Perl Language Reference Manual
by Larry Wall and others
Paperback (6"x9"), 724 pages
ISBN 9781906966027
RRP £29.95 ($39.95)

Sales of this book support The Perl Foundation! Get a printed copy>>>

-i[extension]

specifies that files processed by the <> construct are to be edited in-place. It does this by renaming the input file, opening the output file by the original name, and selecting that output file as the default for print() statements. The extension, if supplied, is used to modify the name of the old file to make a backup copy, following these rules:

If no extension is supplied, no backup is made and the current file is overwritten.

If the extension doesn't contain a *, then it is appended to the end of the current filename as a suffix. If the extension does contain one or more * characters, then each * is replaced with the current filename. In Perl terms, you could think of this as:

($backup = $extension) =~ s/\*/$file_name/g;

This allows you to add a prefix to the backup file, instead of (or in addition to) a suffix:

$ perl -pi'orig_*' -e 's/bar/baz/' fileA    # backup to 'orig_fileA'

Or even to place backup copies of the original files into another directory (provided the directory already exists):

$ perl -pi'old/*.orig' -e 's/bar/baz/' fileA
                                        # backup to 'old/fileA.orig'

These sets of one-liners are equivalent:

$ perl -pi -e 's/bar/baz/' fileA            # overwrite current file
$ perl -pi'*' -e 's/bar/baz/' fileA         # overwrite current file
$ perl -pi'.orig' -e 's/bar/baz/' fileA     # backup to 'fileA.orig'
$ perl -pi'*.orig' -e 's/bar/baz/' fileA    # backup to 'fileA.orig'

From the shell, saying

$ perl -p -i.orig -e "s/foo/bar/; ... "

is the same as using the program:

#!/usr/bin/perl -pi.orig
s/foo/bar/;

which is equivalent to

#!/usr/bin/perl
$extension = '.orig';
LINE: while (<>) {
    if ($ARGV ne $oldargv) {
        if ($extension !~ /\*/) {
            $backup = $ARGV . $extension;
        }
        else {
            ($backup = $extension) =~ s/\*/$ARGV/g;
        }
        rename($ARGV, $backup);
        open(ARGVOUT, ">$ARGV");
        select(ARGVOUT);
        $oldargv = $ARGV;
    }
    s/foo/bar/;
}
continue {
    print;  # this prints to original filename
}
select(STDOUT);

except that the -i form doesn't need to compare $ARGV to $oldargv to know when the filename has changed. It does, however, use ARGVOUT for the selected filehandle. Note that STDOUT is restored as the default output filehandle after the loop.

As shown above, Perl creates the backup file whether or not any output is actually changed. So this is just a fancy way to copy files:

$ perl -p -i'/some/file/path/*' -e 1 file1 file2 file3...
or
$ perl -p -i'.orig' -e 1 file1 file2 file3...

You can use eof without parentheses to locate the end of each input file, in case you want to append to each file, or reset line numbering (see example in ).

If, for a given file, Perl is unable to create the backup file as specified in the extension then it will skip that file and continue on with the next one (if it exists).

For a discussion of issues surrounding file permissions and -i, see "Why does Perl let me delete read-only files? Why does -i clobber protected files? Isn't this a bug in Perl?" (perlfaq5) in the Perl FAQ.

You cannot use -i to create directories or to strip extensions from files.

Perl does not expand ~ in filenames, which is good, since some folks use it for their backup files:

$ perl -pi~ -e 's/foo/bar/' file1 file2 file3...

Note that because -i renames or deletes the original file before creating a new file of the same name, Unix-style soft and hard links will not be preserved.

Finally, the -i switch does not impede execution when no files are given on the command line. In this case, no backup is made (the original file cannot, of course, be determined) and processing proceeds from STDIN to STDOUT as might be expected.

ISBN 9781906966027Perl Language Reference ManualSee the print edition