Number substitution with sed

Hello,

Here is what i'm trying to do :
I want to replace any occurence of the string "abc=123" by "abc=999" except if the pattern is followed by a digit (I want to replace only "abc=123" and not "abc=1234")

One of the most promissing command I tried was :

 
echo 'abc=123
abc=1234
xyzabc=123&fghij=555&abc=123
abc=234'|sed 's/abc=123[^0-9]/abc=999/g'

but the output is :

abc=123
abc=1234
xyzabc=999fghij=555&abc=123
abc=234

What I'm trying to get is :

abc=999
abc=1234
xyzabc=999&fghij=555&abc=999
abc=234

Can anyone help ?

$ echo 'abc=123
abc=1234
xyzabc=123&fghij=555&abc=123 abc=234' | sed 's/\b123\b/999/g'
Output:
abc=999
abc=1234
xyzabc=999&fghij=555&abc=999 abc=234

You're matching the non-digit as part of the sed expression, but not including it in the replacement (hence your lost '&'). Try something like:

sed 's/abc=123\([^0-9]\)/abc=999\1/g'

( \1 is whatever matched the first bracket expression \(...\) )

1 Like

This isn't maybe the best way, but it does work:

sed -E 's/$/./; s/abc=123([^0-9])/abc=999\1/g; s/.$//;'

At least with your small example.

If you are using AT&T's AST sed, or a BSD flavour of sed the -E option will be different.

---------- Post updated at 11:53 ---------- Previous update was at 11:49 ----------

@CarloM -- my thought exactly, but it still wasn't treating the newline as [^0-9], so I added the dot to ensure abc=123$ had some character after it. Maybe I was doing something wrong, but I couldn't get it to work just with the back reference.

Did I miss something?

1 Like

sed -E uses ERE, so it should know alternation:

sed -E 's/abc=123([^0-9]|$)/abc=999\1/g'
3 Likes

More likely I didn't notice, but I can't check right now.

Hi guys !
Thanks for all your messages !
I didn't think it would be so quick!

The -E option doesn't work with my sed (I'm on SunOS 5.10) so I'm now using this :

echo 'abc=123
abc=1234
xyzabc=123&fghij=555&abc=123abc=234' | sed -e 's/abc=123$/abc=999/g' -e 's/abc=123\([^0-9]\)/abc=999\1/g'

This is ok for me but I'd like to know if there's a better way...