Want to edit a file in place (substitute a column value) based on a value in another column in the same file

StackOverflow https://stackoverflow.com/questions/12450025

Question

I want to edit a file in place (substitute a column value) based on a value in another column in same file. I don't want to redirect the output after substitution to another file but rather would want to edit the file in place. Specifically need this because file which needs to be edited will be accessed by no of programs simultaneously and in-place editing is must for this

I tried code below. but this is again writing to input file line by line

#!/usr/bin/perl -w

open(FILEIN, "/dummy/chaat/h2") || die("Cannot open file");
@file = <FILEIN>;
seek FILEIN, 0, 0;

foreach $file (@file) {
    @field = split(/\|/, $file);
    print $field[8] . "\n";
    if ($field[8] eq "ROBERT") {
        $file =~ s/JAMES/FUDIK/g;
        print FILEIN $file;
    }
}

My sample records are as shown below. Here I want to do inline editing of this. if field 8 is ROBERT then substitute JAMES with FUDIK in field 7

Change|sinmg|ewfewf|ewfew|def|fdfd|JAMES|rewr|ROBERT|dsf|fe
Change|sinmg|ewfewf|ewfew|def|JAMES|fewf|rewr|BEASLEY|dsf|fe

I would appreciate any help on this

Was it helpful?

Solution

This is a perl one-liner:

perl -F'\|' -i -lape 'if ($F[8] eq "ROBERT") { s/JAMES/FUDIK/g }' /dummy/chaat/h2

The -i option will do the in-place edit. You may wish to restrict the substitution to avoid partial matches, e.g.:

s/(?<=\|)JAMES(?=\|)/FUDIK/g

Or you can use the -n switch instead of -p and do

s/JAMES/FUDIK/g for @F } print join "|", @F;

You should be aware that this in-place edit is in fact writing a new file, and copying over the old. If you want to avoid this, you need to do some serious juggling, and probably lock the file during writing.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top