newkid
newkid

Reputation: 1468

grep and replace string spread over several lines

I have a string which I want to replace. It is of the format:

  VAL1          = "D_AC" ,
  VAL2          = "DRC" ,
  VALX2         = 3.33330000e+04, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 

Note that the string has both double quotes and newline characters.

I want to replace it with another string:

  VAL1          = "D_AC" ,
  VAL2          = "DRC" ,
  VALX2         = 2.22110000e+04, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 

Ive tried:

export OLD_STRING1="  VAL1          = \"D_AC\" ,"
export OLD_STRING2="  VAL2          = \"DRC\" ,"
export OLD_STRING3="  VALX2         = 3.33330000e+04, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, "

export NEW_STRING1="  VAL1          = \"D_AC\" ,"
export NEW_STRING2="  VAL2          = \"DRC\" ,"
export NEW_STRING3="  VALX2         = 2.22110000e+04, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, "

Then called grep and sed as so:

find . -type f -name '*filename*' -exec sed -i '' s/$OLD_STRING1$OLD_STRING2$OLD_STRING3/$NEW_STRING1$NEW_STRING2$NEW_STRING3/ {} +

sed generates an error:

sed: 1: "s/BX2          = "D_AC ...": unterminated substitute pattern

How could I resolve this?

Upvotes: 0

Views: 92

Answers (1)

Ed Morton
Ed Morton

Reputation: 204258

This would be a nightmare to try to do robustly and portably with sed since sed doesn't understand literal strings (see Is it possible to escape regex metacharacters reliably with sed).

Given this input where you want to change file such that the text contained in old becomes the text contained in new:

$ cat old
  VAL1          = "D_AC" ,
  VAL2          = "DRC" ,
  VALX2         = 3.33330000e+04, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
$
$ cat new
  VAL1          = "D_AC" ,
  VAL2          = "DRC" ,
  VALX2         = 2.22110000e+04, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
$
$ cat file
foo
  VAL1          = "D_AC" ,
  VAL2          = "DRC" ,
  VALX2         = 3.33330000e+04, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
bar

and this script:

$ cat tst.awk
FILENAME==ARGV[1] { old=$0; next }
FILENAME==ARGV[2] { new=$0; next }
s=index($0,old) {
    $0 = substr($0,1,s-1) new substr($0,s+length(old))
}
{ print }

it's this simple:

$ awk -v RS= -f tst.awk old new file
foo
  VAL1          = "D_AC" ,
  VAL2          = "DRC" ,
  VALX2         = 2.22110000e+04, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
bar

Upvotes: 1

Related Questions