Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

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?

share|improve this question

1 Answer 1

up vote 4 down vote accepted

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
share|improve this answer
    
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

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.