Issue
If I have a string like:
p1 and p11 are going to visit p111. p1 is the father of p111
How could I use sed (or anything, really) to replace each instance of p{n} with a different value? So that the result would be something like:
Bob and Jane are going to visit Paul. Bob is the father of Paul
Basically, I'm looking for a way to tell sed, "Find exactly p{n} followed by anything other than a number, and replace it with $var, but don't replace the thing that follows {n}."
If I do something simple like
text="p1 and p11 are going to visit p111. p1 is the father of p111"
text=`echo "$text" | sed s/p1/Bob/g`
I end up replacing every occurrence of "p1" with "Bob," and no subsequent substitutions can take place:
Bob and Bob1 are going to visit Bob11. Bob is the father of Bob11
The closest I've come is something like
text=`echo "$text" | sed 's/p1[^0-9]/bob/g'`
This has two problems: It consumes the trailing character (space, punctuation), and it doesn't match p{n} at the end of a line. After looping through everything that needs to be replaced:
Boband Janeare going to visit Paul Bobis the father of p111
Anyone have an idea how I can find what I need to replace, not insert into other variables, and not consume the trailing non-digit character?
Thanks.
Solution
Sure. The trick is to preserve anything that you do not want to lose using matched groups, delimited by escaped parentheses, and brought into the replacement string using backreferences \1
, \2
, ..., \9
:
s/p1\([^0-9]\)/Bob\1/g
There is also an alternative method, lookaheads, that may or may not be available in your version of sed
, and if it is, requires enabling its "perl mode" of regex syntax.
Answered By - Jirka Hanika Answer Checked By - Dawn Plyler (WPSolving Volunteer)