如何在perl中删除JSON对象

时间:2014-07-18 07:47:25

标签: json perl

我正在开发一个JSON配置文件(logstash-forwarder),我想在其中添加或删除带有perl脚本的数据(它是用于部署或取消部署jboss webapps的脚本,然后可以用它来更新logstash转发器配置)。

添加和修改配置文件没有问题,但我找不到删除对象的正确方法。

以下是config.json文件的示例:

{    
    "network" : {
          "timeout" : 15,
          "ssl ca" : "/etc/logstash-forwarder/cert/logstash-forwarder.crt",
          "servers" : [
             "server1@domain:5043",
             "server2@domain:5043"
          ]    },    
    "files" : [
          {
             "fields" : {
                "environment" : "TEST1,TEST23",
                "application" : "application1",
                "type" : "jboss"
             },
             "paths" : [
                "/path/to/application1/logs/*.log"
             ]
          },
          {
             "fields" : {
                "environment" : "TEST2",
                "application" : "application2",
                "type" : "jboss"
             },
             "paths" : [
                "/path/to/application2/logs/*.log"
             ]
          }    
     ]
}

我用来删除对象的部分代码(当取消部署webapp时):

removeLogStashConf
{
    use JSON qw(encode_json decode_json);

    my ( $application ) = @_;

    my $app_path    = "/path/to/$application/*.log";

    local $/;
    open( my $fh, "<", "$Param::logstash_conf_file" );
    my $json = <$fh>;
    close $fh;

    my $data = JSON::decode_json($json); };

    my @files              = @{ $data->{'files'} };
    my $file_level         = undef;

    foreach my $f (@files) {
        my @paths = @{ $f->{"paths"} };
        foreach my $path (@paths) {
            if ( $path eq $app_path ) {
                $file_level         = $f;
            }
        }
    }

    for (keys %$file_level)
    {
        delete $file_level->{$_};
    }


    my $encoded = JSON->new->utf8->pretty->encode($data);
    open( $fh, ">", "$Param::logstash_conf_file" );
    print $fh $encoded;
}

当我尝试删除application2时,我在config.json文件中得到的结果是:

{    
    "network" : {
          "timeout" : 15,
          "ssl ca" : "/etc/logstash-forwarder/cert/logstash-forwarder.crt",
          "servers" : [
             "server1@domain:5043",
             "server2@domain:5043"
          ]    },
    "files" : [
          {
             "fields" : {
                "environment" : "TEST1,TEST23",
                "application" : "application1",
                "type" : "jboss"
             },
             "paths" : [
                "/path/to/application1/logs/*.log"
             ]
          },
          {}    
     ] 
}

我如何摆脱剩余的 empy花括号(“ {} ”或“ {},”如果我删除不是最后一个数组的应用程序,阻止我进一步解析,让我用一个不整齐的config.json文件。

我当然可以找到一个带有sed的解决方案,但是有更清洁的东西吗?

提前感谢您的帮助。

1 个答案:

答案 0 :(得分:2)

清空哈希是不足以从数组中删除它。

您可以使用splice或只将所有需要的记录复制到新阵列:

my $data = JSON::decode_json($json);

my @files = @{ $data->{'files'} };
my @new_files;

foreach my $f (@files) {
    my @paths = @{ $f->{paths} };
    foreach my $path (@paths) {
        unless ( $path eq $app_path ) {
            push @new_files, $f;
        }
    }
}

$data->{files} = \@new_files;