使用perl更新Conf文件

时间:2014-02-14 06:48:23

标签: linux perl perl-module

我使用perl脚本来更新conf文件中的部分。我的脚本我正常工作,但当我执行脚本时,自动更改部分的命令,而我不想更改order.script正在跟随。

#!/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

请在这里帮助我,我不想改变字段的顺序

2 个答案:

答案 0 :(得分:2)

来自Config :: Tiny的文档:

  

... Config :: Tiny不会保留您的评论,空格或配置文件的顺序。   请参阅Config :: Tiny :: Ordered(以及可能的其他)以保存文件中条目的顺序。

所以,按照文档的建议,看看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 perlreftutperldoc perldsc,以及此处使用的任何未立即明确的功能的文档。

答案 1 :(得分:1)

来自CPAN page

  

最后,Config :: Tiny不会保留您的评论,空格或配置文件的顺序。

使用COnfig::Tiny::Ordered代替

  

请参阅Config :: Tiny :: Ordered(以及可能还有其他人)以保存文件中条目的顺序。