我正在使用 perl 脚本来更新 conf 文件中的部分。我的脚本工作正常,但是当我执行脚本时,各部分的顺序会自动更改,而我不想更改顺序。脚本如下。
#!/usr/bin/perl
use Config::Tiny;
$file = 'sss.conf';
my $Config = Config::Tiny->new;
$Config = Config::Tiny->read( $file );
my $rootproperty = $Config->{_}->{rootproperty};
$Config->{amrit}->{host} = 'Not Bar!';
$Config->write( $file );
以及以下行的文件内容;
[amrit]
type=friend
host=111.118.253.145
port=2776
username=amrit
secret=password
disallow=all
allow=gsm
context=sip-calling
qualify=yes
call-limit=22
请在这里帮助我,我不想更改字段的顺序
最佳答案
来自 Config::Tiny 的文档:
...Config::Tiny does not preserve your comments, whitespace, or the order of your config file. See Config::Tiny::Ordered (and possibly others) for the preservation of the order of the entries in the file.
因此,请按照文档的建议进行操作,并查看 Config::Tiny::Ordered。
更新:根据评论,我将尝试在此处提供其他帮助。
首先,您现有的脚本大多只是从 Config::Tiny 概要中复制粘贴的内容,而对其大部分功能没有任何深入的了解。相关部分...或者至少您应该保留的部分是:
use Config::Tiny;
$file = 'sss.conf';
$Config = Config::Tiny->read( $file );
$Config->{amrit}->{host} = 'Not Bar!';
$Config->write( $file );
如果您在脚本顶部添加 use Data::Dumper;
,并在读取配置文件后立即添加 print Dumper $Config;
,结构将如下所示:
{
'amrit' => {
'call-limit' => '22',
'host' => '111.118.253.145',
'secret' => 'password',
'context' => 'sip-calling',
'port' => '2776',
'username' => 'amrit',
'allow' => 'gsm',
'qualify' => 'yes',
'type' => 'friend',
'disallow' => 'all'
}
}
如果您不介意键/值对重新排列顺序,则可以使用我上面发布的脚本修改结构。但你需要维持秩序。因此建议切换到 Config::Tiny::Ordered。该模块通过以不同方式重新排列结构来保持顺序。如果将脚本更改为如下所示:
use Data::Dumper;
use Config::Tiny::Ordered;
$file = 'conf.conf';
$Config = Config::Tiny->read( $file );
print Dumper $Config;
您将看到结构现在如下所示:
{
'amrit' =>
[
{
'value' => 'friend',
'key' => 'type'
},
{
'key' => 'host',
'value' => '111.118.253.145'
},
{
'value' => '2776',
'key' => 'port'
},
{
'value' => 'amrit',
'key' => 'username'
},
{
'value' => 'password',
'key' => 'secret'
},
{
'value' => 'all',
'key' => 'disallow'
},
{
'key' => 'allow',
'value' => 'gsm'
},
{
'key' => 'context',
'value' => 'sip-calling'
},
{
'key' => 'qualify',
'value' => 'yes'
},
{
'value' => '22',
'key' => 'call-limit'
}
]
}
或者换句话说,Config::Tiny::* 对象的内部结构已经从哈希的哈希变成了哈希数组的哈希。 (“计算机科学中的所有问题都可以通过另一级间接解决”- David Wheeler)数据结构形状的这种变化是为了摆脱散列是无序容器的问题。
因此,现在您不必对名为“host”的键进行方便的哈希查找,而是必须迭代结构以查找具有名为 host 的键字段的匿名哈希的数组元素。更多工作:
use List::Util qw(first);
use Config::Tiny::Ordered;
$file = 'sss.conf';
$Config = Config::Tiny::Ordered->read( $file );
my $want_ix = first {
$Config->{amrit}[$_]{key} eq 'host'
} 0 .. $#{$Config->{amrit}};
$Config->{amrit}[$want_ix]{value} = 'Not Bar!';
$Config->write( $file );
其工作原理是运行配置文件的 amrit
部分,在结构的匿名数组中查找具有名为“key”字段的匿名哈希的元素,一旦找到该数组元素,将“value”哈希元素修改为“Not Bar!”
如果这对您来说只是一次性的事情,那么您就完成了。如果您希望下次能够自己完成此操作,请阅读 perldoc perlreftut
、perldoc perldsc
以及此处使用的任何尚不明确的函数的文档。
关于linux - 使用 perl 更新 Conf 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21772599/