Sed: global substitution - how to ignore a particular range of positions in one particular line

Viewed 76

I want to do a globel substitution of all occurrances of string "apple" to "banana", except for the second occurance of "apple" in line 214. The second occurance of "apple" has the line position of 13 to 17.

For example, line 214 looks like this right now:

apple.pineapplejuice();

I want this line to be changed to (the "apple" in "pineapplejuice() is not changed"

banana.pineapplejuice();

Some example usage of apple in the rest of my file

SetupTable(apple, {isWashed, okay});

I have tried finding answers in these posts, but cannot find what I need: sed replace space character at the 8th position from selected text / How to use sed and cut to find and replace value at certain position of line in a file

Code that I have tried:

sed -i -e '214\{13,17\}!s/apple/banana/g' src/test/fruit.cpp

and i got

sed: 1: "214\{13,17\}!s/apple/ba ...": invalid command code \

I think I just need to know how to specify the address of a particular range of characters on a particular line to make this work, but maybe there are other more clever approaches than this. Thanks in advance!

2 Answers

sed is a (turing complete) scripting language. You can write conditions:

sed '
   214{
      # line 214 handled spexially
      s/apple/banana/
   }
   214!{
      # all except line 214
      s/apple/banana/g
   }
'

or you could '214{s/apple/banana;b;}; s/apple/banana/g' jump to beginning of the script if 214 line is found.

I believe you just want to use GNU sed extensions and match the word apple:

sed 's/\<apple\>/banana/g'

In GNU sed, replace apple as a whole word with

sed -i 's/\bapple\b/banana/g' file

\b is a word boundary.

Related