我计划替换文件中的某些字符串;因此我使用 sed。
我希望替换该字符串,而 sed 则读取该字符串并将文本附加到字符串的中间。
例子:
string in myfile : user=blabla
string that I want to obtain: user=bob
所以我以这种方式运行 sed,让它搜索“user=”字符串,并将其替换为“user=bob”
sed -i 's/user=*/user=bob/' myfile
我得到的是
user=bobblabla
基本上,sed 认为我只想替换那部分,而我想用新字符串替换整个字符串。我以为 * 会告诉 sed 考虑后面的任何内容,但它不起作用。
由于我不知道“blabla”是什么,所以我无法将其放入 sed 命令中。我该如何告诉 sed 查找以“user=”开头的字符串并用新字符串替换整个字符串?
答案1
您似乎将 shell 模式与正则表达式混淆了。在 shell 模式中,*
表示零个或多个任意字符。在正则表达式中(即sed
其模式所期望的),*
表示零个或多个前一个原子。在您的示例中,该原子是=
。因此,sed
搜索user
后跟零个或多个=
并将匹配的字符串替换为user=bob
。您想要的模式是user=.*
,user=
后跟任意字符(.
)零次或多次,从而使您的sed
命令:
sed -i 's/user=.*/user=bob/' myfile
答案2
正如 GaryJohn 所说,您的正则表达式错误。(* -> .*)
但是我会更进一步,当你这样做的时候......我不知道你的文件实际上是什么样的,但只是为了练习,我会研究如何让你的搜索/替换操作更安全一些。
假设你想在这样的文件上运行该程序:
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
使用您当前的 sed 语法,这将会非常错误。为了更具体一点,您可以尝试:
sed -i 's/^user=[A-Za-z0-9_]*/user=bob/g' /tmp/myfile
这会:
- 仅当行实际以“用户”(^)开头时才触发
- 仅更改“user=”由 0 个或多个字母、数字或下划线组成
- 保留用户名后面的所有内容(即我的示例中的注释)
这绝不是一个超级安全的方法,无论何时何地,只要你想重命名用户,它都会起作用。显然,这取决于你的配置文件是如何设置的,以及你期望遇到什么。但我的回答是为了提供一些“思考的素材”,因为给定一个足够大的配置文件,可以预料到会有这么多的用户名不想手动执行此操作,盲目替换“user=.*”似乎很危险。你可能需要花一些时间来完善这些类型的操作 :)
祝你好运。