使用Perl解析JSON

使用Perl解析JSON,perl,perl-module,Perl,Perl Module,我已经编写了一个测试脚本来执行某些功能。脚本按预期工作。目前,运行脚本所需的参数是使用Getopt::Long从命令行传递的。我想将命令行参数移动到json文件中。端点ip仍将作为命令行参数传递。 我希望端点ip充当密钥。例如,如果端点是1.1.1.1,我想获取下面提到的json配置文件中端点id 1.1.1下列出的客户端ip、客户端接口ip、originip等端口。我该怎么做 脚本的当前版本: use Getopt::Long; my ($self) = @_;

我已经编写了一个测试脚本来执行某些功能。脚本按预期工作。目前,运行脚本所需的参数是使用
Getopt::Long
从命令行传递的。我想将命令行参数移动到json文件中。端点ip仍将作为命令行参数传递。 我希望端点ip充当密钥。例如,如果端点是1.1.1.1,我想获取下面提到的json配置文件中端点id 1.1.1下列出的客户端ip、客户端接口ip、originip等端口。我该怎么做

脚本的当前版本:

 use Getopt::Long;

     my ($self) = @_;

        GetOptions (
            "endpoint|e=s"           => \$self->{'endpoint'},
            "aggregator|a=s"         => \$self->{'aggregator'},
            "port|pt=s"              => \$self->{'port'},
            "client|c=s"             => \$self->{'client'},
            "client_interface|ci=s"  => \$self->{'client_interface'},
            "origin|o=s"             => \$self->{'origin'},
            "origin_interface|oi=s"  => \$self->{'origin_interface'},
            "interfacename|ot=s"     => \$self->{'i1'},
            "interfacename2|it=s"    => \$self->{'i2'},
             ) || $self->abort( "Invalid command line options.
                   Valid options are endpoint,aggregator,port,client,client_interface,
                     origin,origin_interface,outertunnel,innertunnel,");

       #Terminate the script execution if the reqd args are not passed
       my @required_args = qw(endpoint aggregator port client client_interface            origin origin_interface 
                              );

       for my $command_line_arguments (@required_args) {
         unless ($self->{$command_line_arguments}) {
          $self->abort('missing required argument ' . $command_line_arguments);
         }
       }

  $self->{'tObj'} =  QA::crypto::tunnels->new
      ('host'=> $self->{'endpoint'})
         or $self->abort('[Could not create a QA::Crypto::tunnels object.]');
参数的json文件:

{
        "Endpoints": [{

                "endpoint": "1.1.1.1",
                "client_ip": "3.4.5.6",
                "client_interface_ip": "10.11.12.14",
                "origin": "a.a.a.a",
                "origin_interface": "15.16.17.18",
                "interfacename": "name",
                "interfacename2": "name1",
                "sl": 19,
                "port": 362
        }, {

                "endpoint": "2.2.2.2",
                "client_ip": "19.20.21.22",
                "client_interface_ip": "23.24.25.26",
                "origin": "1.2.3.4",
                "origin_interface": "5.6.7.8",
                "interfacename": "interface name",
                "interfacename2": "interfacename_2",
                "sl": 19,
                "port": 366
        }]
}




#!/usr/bin/perl

use strict;
use warnings;
use JSON;

my $json;
{
   open my $fh, "<", "cfg.txt"
      or die("Can't open file \"cfg.json\": $!\n");
   local $/;
   $json = <$fh>;
}

my $data = decode_json($json);
$json = JSON->new->utf8->pretty->encode($data);
{
“端点”:[{
“端点”:“1.1.1.1”,
“客户ip”:“3.4.5.6”,
“客户端接口ip”:“10.11.12.14”,
“起源”:“a.a.a.a”,
“原始接口”:“15.16.17.18”,
“接口名称”:“名称”,
“interfacename2”:“name1”,
“sl”:19,
“港口”:362
}, {
“端点”:“2.2.2.2”,
“客户ip”:“19.20.21.22”,
“客户端接口ip”:“23.24.25.26”,
“来源”:“1.2.3.4”,
“原始接口”:“5.6.7.8”,
“接口名称”:“接口名称”,
“接口名称2”:“接口名称2”,
“sl”:19,
“港口”:366
}]
}
#!/usr/bin/perl
严格使用;
使用警告;
使用JSON;
我的$json;
{

打开我的$fh,“第一个问题是关于JSON文件的合适设计。哈希在这里可以很好地使用,而arrayref似乎根本不需要。端点值可以是键,它们的值是带有键相关信息的hashref。如果愿意,也可以将端点值保留在其hashref中

JSON中的键
“Endpoints”
似乎没有什么作用。但是如果您确实需要它,也许因为会有其他类型的键,那么您可以为其值使用另一个hashref,它将包含作为键的端点值的hashref

比如说

{ "Endpoints": { "1.1.1.1": { "client_ip": "3.4.5.6", ... }, "2.2.2.2": { "client_ip": "19.20.21.22", ... }, ... }, "OtherKeys": { ... }, ... } 然后,检索这些值的方法很简单,如下所示

my $client_ip = $data->{Endpoints}{'1.1.1.1'}{client_ip};
例如,检索所有端点并为它们列出
client\u ip

my @endpoints = keys %{$data->{Endpoints}};
foreach my $ip (@endpoints) {
    say $data->{Endpoints}{$ip}{client_ip};
}
看,完全是关于它的。也看和

我们可以使用

还有许多其他用于处理嵌套数据结构的包


请注意,该软件包附带了
encode_json
和相关方法,因此您可以通过编程方式创建该文件。这可能有助于获得正确的格式,并有助于将来的维护。

如果我想获得endpoint 1.1.1.1的客户端ip,我该怎么做?@nims-Ah,对。已添加到答案中。我将添加一些参考处理hashref也是一样。@nims我添加了一些处理hashref的引用,这是第一个用于此用途的引用。让我知道hashref业务是否有问题——这对于顺利使用JSON来说至关重要。my$JSON='{“Endpoints”:{“198.18.193.126”:{“client_ip”:“3.4.5.6”,“client_interface_ip”“:”9.1.1.2“,”原点“:”198.18.193.151“,”原点接口“:”8.2.0.2“,”外部隧道“:”隧道1“,”内部隧道“:”内部隧道“,”插槽“:”1900,“端口“:”362},}”“;my$j=JSON->new;my$data=$j->decode($JSON);my$client;$client=$data->{Endpoints}{198.18.193.126}{client_ip};print$client;我无法打印$client=$data->{Endpoints}{198.18.193.126}{client_ip}中的值;为什么?
my @endpoints = keys %{$data->{Endpoints}};
foreach my $ip (@endpoints) {
    say $data->{Endpoints}{$ip}{client_ip};
}
use Data::Dumper;
my $data = decode_json($json);
print Dumper($data);