1

Basically I think this question is more one of regex than SED directly, but it’s SED I’m using, so that’s where I’m starting from.

I’ve got a web.config configuration file for an ASP.NET 2.0 website that I’m automating the build process for. I’m using UNIXUtils to give me some extra power over and above that provided by Windows. Using SED can someone enlighten me as to how I'd accomplish the following;

Change

Data Source=RANDOM-SERVER;Initial Catalog=SomeDatabase;Persist Security Info=True;User ID=MyUser;Password=*************;

To

Data Source=PRODUCTION-SERVER;Initial Catalog=SomeDatabase;Persist Security Info=True;User ID=MyUser;Password=*************;

I’ve tried the following

sed s"|Data Source=.*;|Data Source=PRODUCTION-SERVER;|g"

but what I receive is

Data Source=PRODUCTION-SERVER;

i.e. sed is helpfully being ultra greedy and eating all the characters up until the last semicolon, at least that’s what it seems to be doing.

BTW: Yes I would like to retain the |g greedy operator on the end to ensure that the alteration is applied to all occurrences in the original file, though, in theory there shouldn’t be.

If someone can show me how to accomplish this I'd be grateful, though I suspect there isn’t an easy way to do it, as I’ve not been able to find anything on the net that matches my requirements. Annoyingly everybody's focused on paths of one form or another.

If it can’t be done in SED but can be done using something else in the standard UNIXUtils suite, then that’s an acceptable answer, I’m open to suggestions.

1
  • Ahhh, as I suspected it’s a regex issue more than an issue with SED. Also thanks Thor for the clarification with regards to the global flag.
    – Greg
    Commented Aug 23, 2013 at 0:36

2 Answers 2

2

Use a non-matching character-group ([^;]) instead of dot (.), for example:

sed s"|Data Source=[^;]*|Data Source=PRODUCTION-SERVER|"

Note that global (g) flag at the end means "replace all occurrences on the current line" and not greedy.

1
  • g stands for "global" Commented Oct 22, 2018 at 23:04
1

As far as I know, sed has no way of doing non greedy matching, its regexes are always greedy (and as already pointed out the g flag means match all occurrences in the current line, it will search the entire file by default).

I would do this either by using a character group as suggested by @Thor or by using a tool that supports non greedy matches like Perl:

perl -pne 's/Data Source=.+?;/Data Source=PRODUCTION-SERVER;/' file 

In Perl regex, the construct +? means find at least one (+) but as few as possible (?) matching characters. The -p means print each line and the -n means read the input file line by line and apply the script given as an argument to -e. Finally, you can also edit the file in place with the i option:

perl -i -pne 's/Data Source=.+?;/Data Source=PRODUCTION-SERVER;/' file 

You must log in to answer this question.

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