许多配置文件都基于格式Key value
或Key=value
每个配置文件一行。许多软件包提供了默认配置文件,其中这些可用的配置键已使用其默认值写入和/或进行了注释。
我想知道是否有一种工具可以更改此类文件,而无需打开交互式编辑器并且比它更高级别sed
(可能是在它之上构建的)。
这将是简单的事情:
$ conftool file key value
它将在文件中找到密钥,删除注释符号(如果有),更改值并保存结果。
答案1
据我所知,没有通用的配置换线工具。我想创建这样一个工具会很困难,因为有很多不同的配置文件语法。
如果您想更改特定配置文件中的特定值,那么您可以为该特定任务编写专门的工具。
这里有两个使用 sed 和 awk 的示例来帮助您入门
key value
一个简单的 sed 命令,用于替换简单语法的键值
$ sed 's/^key2 value2$/key2 newvalue2/' config
例子
$ cat config
key1 value1
key2 value2
key3 value3
$ sed 's/^key2 value2$/key2 newvalue2/' config
key1 value1
key2 newvalue2
key3 value3
但要注意:如果有更多key2 value2
行(可能在配置文件的其他部分),那么所有行都将被替换。这在 sed 中很难防止(可能但很难),而在 awk 中则更容易。请参阅下文了解尊重节的 awk 命令。
解释:
这个 sed 命令大致执行以下操作:
for every line:
if line is "key2 value2":
print "key2 newvalue2"
这个 sed 命令的s/pattern/replace/
意思是:在每一行中搜索pattern
,如果找到则替换为replace
.pattern
可以是普通字符串或regex(正则表达式)。
正则表达式中的^
和&
称为锚点,分别表示行首和行尾。如果没有锚点,该模式key2 value2
也将匹配该行xkey2 value2x
,结果将是xkey2 newvalue2x
。
以下是我们如何使用模式改变行为的一些示例。
也适用于key=value
语法
$ sed 's/^key2=value2$/key2=newvalue2/' config
无论旧值如何,只匹配键
$ sed 's/^key2=.*/key2=newvalue2/' config
删除可能的评论标志
$ sed 's/^#\?key2 value2$/key2 newvalue2/' config
如果重定向输出,您还可以打印到 stderr 以查看某些内容发生了变化
$ sed 's/^#\?key2 value2$/key2 newvalue2/ w /dev/stderr' config > newconfig
使用正确的正则表达式您可以做更多事情。但这将是另一个问题的另一个答案。
这是一个 awk 脚本,也可以处理配置部分
/^\[section2\]$/ {
print
insection2=1
next
}
insection2 && /^#?key2=value2$/ {
print "key2=newvalue2"
next
}
/^\[.*\]$/ {
insection2=0
}
1
像这样使用
$ awk -f configer.awk config
例子
$ cat config
[section1]
key1=value1
key2=value2
[section2]
key1=value1
key2=value2
[section3]
key1=value1
key2=value2
$ awk -f configer.awk config
[section1]
key1=value1
key2=value2
[section2]
key1=value1
key2=newvalue2
[section3]
key1=value1
key2=value2
您还可以向 stderr 添加详细输出,以便在重定向输出时可以看到发生了什么变化
insection2 && /^#?key2=value2$/ {
print "key2=newvalue2"
print "changed line "NR > "/dev/stderr"
next
}
awk 脚本的简短说明
第一条规则查找[config2]
节标题。它将把insection2
标志设置为 true
第二条规则寻找该key2=value2
行。但前提是该insection2
标志为真。然后它将打印包含新值的行。
第三条规则查找任何其他节标题。它会将insection2
标志重置为 false。
最后一条规则(唯一的1
)是“默认规则”。它只会打印该行不变。
在伪代码中
for every line:
if line is [section2]:
note that we are in section2
else if we are in section2 and line is key2=value2:
print modified line
else if line is any other section header:
note that we are no longer in section2
else
print line unchanged