3

I have a script that finds a string in a file replaces it with a new string.

$ sed -i 's/$old_string'/'$new_string'/g' $FILENAME

Now I need the condition to be a regular expression that also check whether the old string is followed with anything but a number.

I tried this but it didn't work:

$ sed -i -r 's/$old_string(^[0-9])+/$new_string/g' $FILENAME

Any idea?

Khaled
  • 35,688
  • 8
  • 69
  • 98
edotan
  • 1,786
  • 12
  • 37
  • 57

1 Answers1

7

To negate a range in a regular expression, the caret must be inside the square brackets.

sed -i -r 's/$old_string([^0-9])+/$new_string/g' $FILENAME

The parentheses are also unnecessary in this case if you are not using backreferences (and it doesn't look like you are.)

sed -i -r 's/$old_string[^0-9]+/$new_string/g' $FILENAME

One last thing: bash doesn't parse variables inside single-quotes, so $old_string and $new_string will not be replaced by any bash variable you may have set in your script but will be used literally in that sed command. If you use double-quotes, they will be replaced.

sed -i -r "s/$old_string[^0-9]+/$new_string/g" $FILENAME

Update:

Since the file doesn't contain anything after the string you want to replace, the [^0-9]+ part of the regex has nothing to match. It would work if there was a space after the IP address. We can match the end of the line instead with $.

sed -i -r 's/123.123.123.1$/4.4.4.4/g' $FILENAME

One more update. This one matches any character that isn't a number or no characters at all. For this one we need the parentheses to group the two options.

sed -i -r 's/123.123.123.1([^0-9]+|$)/4.4.4.4/g' $FILENAME

Since we have the parentheses, you can use a backreference to include whatever was matched:

sed -i -r 's/123.123.123.1([^0-9]+|$)/4.4.4.4\1/g' $FILENAME
Ladadadada
  • 25,847
  • 7
  • 57
  • 90
  • Tried to do as you explained but it doesnt work, here is the command i tried: sed -i -r "s/123.123.123.1[^0-9]+/4.4.4.4/g" test while the file named test contains: 123.123.123.100 123.123.123.1 The result was that nothing happened. – edotan Apr 18 '12 at 10:10
  • Ah, I see the problem. Updated answer. – Ladadadada Apr 18 '12 at 10:33
  • Once again you miss understood me :). As i said in my original post, ANYTHING can follow the matched string BUT a number. Anything includes nothing. For example if im looking to replace "aaa" with "xxx" so "aaaB" will turn to "xxxB" and "aaa<" will be replaced by "xxx<" BUT "aaa3" will stay "aaa3" – edotan Apr 18 '12 at 10:51