I need to edit a file in place within a perl script, so the oft used one liner:

perl -p -e s/<value>/<value>/ig 

will not work for this situation. How do I get the same results from within a perl script?

open(CRONTAB, "+<file" || die "...";

while (<CRONTAB>) { 
   if ($_ =~ /value/) {  
      print "$_\n";  

My print is showing exactly what I want. It's just the in place edit that I'm looking for.

  • 1
    You might get better answers on StackOverflow.com If you want it moved, flag it for moderator attention. If you want to maintain ownership, make sure your accounts are associated. Sep 8, 2009 at 18:10

4 Answers 4

do {
  local $^I='.bak'; # see perlvar(1)
  local @ARGV=("file");

Beware though: $^I like perl's -i isn't crashproof.

  • This seems to jive with what I've seen on other sites for a way to in-place edit. I was hoping for something as fast and painfree as the oneliner but this works too. Much thanks. Sep 4, 2009 at 22:40
  • aaarrrghhh. s/jive/jibe/ - "jive" is a style of music or dance. the word you are looking for is "jibe" - "Jibe \Jibe\, v. i. [...] 2. To agree; to harmonize. [Colloq.] --Bartlett.". sorry, just one of the things that bug me like people spelling the two words "a lot" as one word "alot".
    – cas
    Sep 5, 2009 at 2:06
  • s/// will replace regex. What if I want to delete(not replace with blank line) a line that match the regex. Also How to avoid backups?
    – balki
    Jan 27, 2011 at 6:14
  • @balki you should create a new question.
    – geocar
    Mar 13, 2011 at 1:13

Your edit appear pretty simple. Have you considered simply using sed with the -i option?

  • I've not considered it. I've never used sed before within a perl script. I'd prefer to do it using perl if possible. I suppose I could backtick the perl -p -e statement in the script too, but it's kind of ugly. Thanks for the thought, though. Sep 4, 2009 at 19:38

Try this, based on the translation of -i in perldoc perlrun:

use strict;
use warnings;
my $filename = "something";
my $extension = '.orig';
while (<>) {
    my $backup;
    if ($extension !~ /\*/) {
        $backup = $filename . $extension;
    else {
        ($backup = $extension) =~ s/\*/$filename/g;
    rename $filename, $backup;
    open my $outfile, '>', $filename;
    select $outfile;
    s/^\#+// if /value/; 
continue {
    print;  # this prints to original filename
select STDOUT;
  • 1
    Seriously too much work, given that $^I is the precise equivalent for the command line -i. Oct 29, 2009 at 1:03

use File::Inplace

Also, it has commit/rollback after you've got all your changes in place for a file....

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.