mozman2
mozman2

Reputation: 929

Find replace string before and after

I have been trying to do a sed replace. For some reason, I just can't my head around sed and regular expressions (this is my second sed question)

Basically I want to find text and replace then find the next occurrence of some text and replace that

So far I have this

echo "This could be anywhere and this bit should be changed \$\{hcvar-BookName\} and this would remain" | sed 's/$\\{hcvar-/" + hcvar-/g'

This returns:

*This could be anywhere and this bit should be changed " + hcvar-BookName\} and this would remain*

However I want to return

*This could be anywhere and this bit should be changed " + hcvar-BookName + " and this would remain*

This would replace the } with + "

The logic would be something like:

Find: \$\{hcvar-
Replace with:  " + hcvar-
Then find the next occurrence of: \}
Replace with: + "

The second bit to replace would be right after the string that contains: hcvar-

This should work for the following string examples

Any help would be appreciated.

Upvotes: 0

Views: 87

Answers (2)

Andreas Louv
Andreas Louv

Reputation: 47119

Assuming that your input is actually:

... changed ${hcvar-BookName} and ...

Then the following will work:

$ sed 's/${\([^}]*\)}/" + \1 + "/' file.txt
This could be anywhere and this bit should be changed " + hcvar-BookName + " and this would remain

Note use single quotes to preserve what would otherwise be special characters for the shell:

$ echo '...changed ${hcvar-BookName} and ...' | sed '...' 

If the input is does actually use \{ i.e: ... $\{hello\} ..., then this might work:

$ sed 's/$\\{\([^}]*\)\\}/" + \1 + "/' file.txt
This could be anywhere and this bit should be changed " + hcvar-BookName + " and this would remain

Breakdown:

s/            /          / # Replace ... with ...
  ${         }             # Literal ${ and literal }
    \(     \)              # \( and \) is a capturing group
      [^}]*                # Match everything but } zero or more times
               " + \1 + "  # \1 will be expanded to the captured result
                           # from \(, \). The rest is literal

Add the global if you need multiply substitutions on each line:

s/pattern/replacement/g
#                     ^ Global flag

Upvotes: 1

codeforester
codeforester

Reputation: 43039

You need to escape $ with a backslash:

echo "This could be anywhere and this bit should be changed \$\{hcvar-BookName\} and this would remain" | sed -e 's/\$\\{hcvar-/" + hcvar-/g' -e 's/\\}/ +/'

Output:

This could be anywhere and this bit should be changed " + hcvar-BookName + and this would remain

Upvotes: 0

Related Questions