基本上,我认为这个问题更多的是一个正则表达式问题,而不是直接的 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