如何让 SED 仅替换搜索表达式中的第一组字符

如何让 SED 仅替换搜索表达式中的第一组字符

基本上,我认为这个问题更多的是一个正则表达式问题,而不是直接的 SED 问题,但我使用的是 SED,所以我从这里开始。

我有一个用于 ASP.NET 2.0 网站的 web.config 配置文件,我正在自动执行构建过程。我正在使用 UNIXUtils 来获得比 Windows 提供的更多功能。有人能告诉我如何使用 SED 来实现以下功能吗?

改变

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

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

我尝试过以下方法

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

但我收到的是

Data Source=PRODUCTION-SERVER;

也就是说,sed 非常贪婪,它会吃掉直到最后一个分号的所有字符,至少它看起来是这么做的。

顺便说一句:是的,我想保留末尾的 |g 贪婪运算符以确保更改应用于原始文件中的所有出现,但理论上不应该这样做。

如果有人能告诉我如何实现这一点,我将不胜感激,尽管我怀疑没有简单的方法可以做到这一点,因为我在网上找不到符合我要求的东西。令人恼火的是,每个人都专注于这样或那样的路径。

如果无法在 SED 中完成,但可以使用标准 UNIXUtils 套件中的其他工具完成,那么这是一个可以接受的答案,我愿意接受建议。

答案1

使用不匹配的字符组 ( [^;]) 代替点 ( .),例如:

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

g请注意,末尾的全局( )标志表示“替换当前行上的所有出现”,而不是贪婪。

答案2

据我所知,sed没有办法进行非贪婪匹配,它的正则表达式总是贪婪的(并且正如已经指出的标志g意味着匹配当前行中的所有出现,它将默认搜索整个文件)。

我会通过使用字符组来做到这一点建议通过@Thor或使用支持非贪婪匹配的工具(如Perl):

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

在 Perl 正则表达式中,构造+?意味着找到至少一个 ( +) 但尽可能少 ( ?) 个匹配字符。-p意味着打印每一行,而-n意味着逐行读取输入文件并将作为参数给出的脚本应用于-e。最后,您还可以使用以下选项就地编辑文件i

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

相关内容