Last updated
Was this helpful?
Last updated
Was this helpful?
在shell脚本中,需要修改某个配置文件的配置项。比较简单粗暴的方式是,先sed删除掉匹配行,然后再在配置文件末尾echo
方式添加一行。但是这种方式会导致配置文件很混乱,并且对于一些标准的"段落块"INI配置文件会引发问题。
如果有大量的配置需要修改,并且希望标准化配置方法,可以采用。不过,对于短小简单的shell脚本,可以使用sed
来实现配置修改。
key=value
举例,需要将/etc/libvirt/qemu.conf
默认配置
修改成自定义目录;
命令如下:
解释:
-i
表示sed将处理结果直接写入到输入文件,这样就不会打印输出
/^auto_dump_path =/
表示匹配//
之间的内容,这里字符串开头加了^
是为了匹配实际生效的非注释行,就不会匹配到#auto_dump_path =
这样的配置注释内容。^
表示行首。
s/OLD/NEW/
是执行一个替换,OLD
字符串是一个规则匹配到正则表达式,将被替换成NEW
字符串。
在正则表达式中,.*
表示"匹配任何内容",所以这里= .*
就会匹配上等于符号,空格以及其他任何内容。
在替换内容中= "\/myapp\/qemu\/dump"
,使用\/
的\
符号是转义符。
/
)上述一条命令修改配置文件的键值虽然方便,但是在shell脚本中,我们会使用变量,sed是如何使用shell中的变量呢?
方法很简单,就是将我们习惯使用的''
修改成""
,这样在shell脚本中使用sed时,会自动实现变量替换(因为在shell中,双引号中会解析变量):
然而问题来了,由于传递的value
中包含了/
作为路径,对于sed来说,命令分隔符默认就是/
,这会导致传递value
中包含的/
被sed解析成命令分隔符。
sed实际上可以使用其他字符来代替
/
作为分隔符,所以如果你传递的参数中包含了/
,你可以用其他不可能包含在参数中的字符来作为sed的分隔符。例如使用@
或者#
。所以我们的脚本就可以修改成使用#
作为sed分隔符:
sed工具已经考虑过这样的特殊字符操作,不需要使用转义符就可以轻松实现行编辑。
现在我们的脚本改进如下:
仔细观察Linux系统配置文件,常见有两种格式的配置赋值方式,主要区别是=
前后是否存在空格
此外,数值通常不使用引号,字符串则使用引号。
通过以下函数判断传入的参数是否是整数值来确定添加引号,以及通过分析现有配置文件格式的=
前后是否有空格来设置格式
这个问题在提供了解决思路: