7

I am planning to replace certain strings in a file; so I am using sed.

I would like to have the string replaced, while instead, sed read the string and append the text in the middle of the string.

Example:

string in myfile : user=blabla
string that I want to obtain: user=bob

so I run sed in this way, to have it to search for the "user=" string, and replace it with "user=bob"

sed -i 's/user=*/user=bob/' myfile

What I get is

user=bobblabla

Basically sed think that I want to replace just that part, while I want to replace the whole string with the new string. I thought that the * would tell sed to consider anything coming after, but it does not work.

Since I do not know what the "blabla" will be, I can't put it in the sed command. How do I tell sed to find a string that start with "user=" and replace the whole string with the new one?

2 Answers 2

13

You seem to be confusing shell patterns with regular expressions. In a shell pattern, * means zero or more of any character. In a regular expression, which is what sed expects in its patterns, * means zero or more of the previous atom. In your example, that atom is the =. So, sed is searching for user followed by zero or more = and replacing the matching string with user=bob. The pattern you want is user=.*, which is user= followed by any character (.) zero or more times, making your sed command:

sed -i 's/user=.*/user=bob/' myfile
1
  • 1
    Brilliant, thanks a lot! the dot tell any character, so the star will match zero or more of any character, until the end of the string.
    – rataplan
    Jan 27, 2015 at 1:22
5

As GaryJohn said, you got the regex wrong. (* -> .*)

But I'd go a bit further, while you're at it... I don't know what your file is actually like, but just for practice I'd look into making your search/replace operation a bit safer.

Say you want to run the thing over a file like this:

user=john
superuser=jimmy      # don't want to change this line!
user=L33t_us3rn4m3   # that should work too, and these comments should remain intact as well, btw
# in the line below, I want to change user=hello to user=bob
# but in the comments, "user=hello" should remain intact
user=hello

With your current sed syntax, this would go quite wrong. To make it a bit more specific, you could try:

sed -i 's/^user=[A-Za-z0-9_]*/user=bob/g' /tmp/myfile

This will:

  • only trigger when the line actually begins with "user" (the ^)
  • only change "user=" as far as consists of 0 or more letters, digits or underscores
  • leave everything behind the username (i.e. the comments in my example) intact

This is by no means a super safe thing that will work always and everywhere where you want to rename users. Obviously, that depends on how your config file is set up and what you would expect to encounter. But my answer is meant to give a bit of "food for thought", because given a (number of) config file(s) large enough to expect so many user names not want to do this manually, blindly replacing "user=.*" seems possibly dangerous. You may want to spend some time polishing these kinds of operations :)

Good luck.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .