0

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?

3
  • Consider broadening your solution set to perl. As I recall, perl had ready support for this sort of thing. Commented Jan 26, 2019 at 18:21
  • The first 2 lines in the strings are the same. Are you trying to change VALX2, but only after the matches of VAL1 and VAL2 ? Commented Jan 26, 2019 at 23:07
  • This occurs when the script-string is malformed. This is because you didn't properly quote the script-string. You likely didn't use quotes because you wanted bash to apply variable substitution which could be done by alternating a series of single and double quotes where appropriate. Once this is done and sed does properly execute, this is not to say that it will succeed. Anyway, besides that, I find your question-code contradictory with the question-title, where's the spanning multi-line issue? In this case, you can use sed, perl, or w/e. sed is my go-to for this problem, using N to buffer. Commented Jan 27, 2019 at 2:27

1 Answer 1

1

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
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.