Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical

Inplace Editing

by tachyon (Chancellor)
on Aug 21, 2001 at 07:04 UTC ( #106461=snippet: print w/replies, xml ) Need Help??
Description: This comes up so often I thought it deserved a snippet. This code will read all the files in a directory and then inplace edit them acording to a regex. A backup of the original file with the extension .bak is created.
#!/usr/bin/perl -i.bak -w

# A short program to edit all the files in a dir inplace

use strict;

my $dir = 'c:/test1';
my @files;

opendir(DIR, $dir) or die "Can't open dir $dir, Perl says $!\n";
while (my $file = readdir DIR) {
    # only push in the files not the dirs - use full path!
    push @files, "$dir/$file" unless -d "$dir/$file";
closedir DIR;

# now do an inplace edit. use a bare block and local to limit
# the scope of our changes to the global @ARGV array to just here
    local @ARGV = @files;   # set up a temporary @ARGV for in-place ed
    while (<>) {
        s/this/that/;       # modify the file
        print;              # print the modifications
Replies are listed 'Best First'.
Re: Inplace Editing
by rob_au (Abbot) on Aug 21, 2001 at 09:43 UTC
    From the first Camel book, page 253, "Substituting strings in many files":
    perl -pi.bak -e 's/OLDSTRING/NEWSTRING/g' FILELIST


    Ooohhh, Rob no beer function well without!

      Unfortunately, on Win32 platforms the shell does not expand wildcards in FILELIST like on Unix platforms, therefore you need to use something like this there:

      > perl -MFile::DosGlob -i.bak -pe "BEGIN {@ARGV=glob(join ' ', @ARGV)} + s/foo/bar/g" *.txt *.bak

      Christian Lemburg
      Brainbench MVP for Perl

Re: Inplace Editing
by $code or die (Deacon) on Aug 21, 2001 at 17:56 UTC
    if the script is not run with -i, you can do this:
    { local ($^I, @ARGV) = ('.bak', @files); while (<>) { s/this/that/; print; } }
    It's also useful if you ARE running with -i and wish to use a different extension for the backup file.

    Error: Keyboard not attached. Press F1 to continue.
Re: Inplace Editing
by WAP_happens (Initiate) on Aug 21, 2001 at 20:27 UTC
    On the principle that shorter is better I do it like this:

    perl -p -i -n -e 's/this/that/g' *.txt

    BTW when I use -pine for the switches it doesn't work, anyone know why?

      Know your command line switches ;-) ... two things

      • -p and -n contradict each other (and actually p overrides n).
      • -pine switches on the p switch and uses backup files which append ne to the filename - so my suggestion is -pi -e.

      -- Hofmator

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: snippet [id://106461]
erix likes the term condescension detection

How do I use this? | Other CB clients
Other Users?
Others studying the Monastery: (11)
As of 2018-05-24 14:34 GMT
Find Nodes?
    Voting Booth?