edit_file and edit_file_lines


Have you ever wanted to use perl -pi inside perl? Did you have the guts
to localize $^I and @ARGV to do that? Now you can do that with a simple
call to edit_file or edit_file_lines in the new .018 release of
File::Slurp. Now you can modify a file in place with a simple call.

edit_file reads a whole file into $_, calls its code block argument and
writes $_ back out the file. These groups are equivalent operations:

perl -0777 -pi -e 's/foo/bar/g' filename

use File::Slurp qw( edit_file ) ;

edit_file { s/foo/bar/g } 'filename' ;

edit_file sub { s/foo/bar/g }, 'filename' ;

edit_file \&replace_foo, 'filename' ;
sub replace_foo { s/foo/bar/g }

edit_file_lines reads a whole file and puts each line into $_, calls its
code block argument and writes each $_ back out the file. These groups are
equivalent operations:

perl -pi -e '$_ = "" if /foo/' filename

use File::Slurp qw( edit_file_lines ) ;

edit_file_lines { $_ = '' if /foo/ } 'filename' ;

edit_file_lines sub { $_ = '' if /foo/ }, 'filename' ;

edit_file \&delete_foo, 'filename' ;
sub delete_foo { $_ = '' if /foo/ }

So now when someone asks for a simple way to modify a file from inside
Perl, you have an easy answer to give them.

8 Comments

Nice. Scary, but nice.

perl -pi -e '$_ = '' if /foo/' filename

That line just doesn't look right.

Nice, although I'd recommend reversing the order of the arguments so that the code block comes last, ie,

edit_file $filename, {s/foo/bar/g};

Then you'd be forced to write sub, because perl prototypes only accept implicit code blocks as the first parameter.

Nice! I've been wanting this for a while.

Does it read the entire file into memory at once? Seems awfully wasteful.

Text::Ased ... not quite as simple, but it lets you do replacements only on lines that satisfy a condition

Leave a comment

About Uri

user-pic I place Perl developers and I also do Perl support and consulting.