2016-09-21 4 views
2

Я написал тестовый скрипт для выполнения определенных функций. Скрипт работает так, как ожидалось. В настоящее время аргументы, необходимые для запуска сценария, передаются из командной строки с использованием Getopt::Long. Я хотел бы переместить аргументы командной строки в json-файл. Endpoint ip по-прежнему будет передаваться как аргумент командной строки. Я хочу, чтобы конечная точка ip действовала как ключ. Например, если конечная точка равна 1.1.1.1, я хочу получить порт client_ip, client_interface_ip, originip, ...., который указан под идентификатором конечной точки 1.1.1.1 в файле конфигурации json, указанном ниже. Как мне это сделать ?Parse json array с использованием perl

текущая версия сценария:

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); 

ответ

2

Первый вопрос о подходящем дизайне для файла JSON. Хеши могут хорошо обслуживаться здесь, в то время как arrayref вообще не нужен. Конечными значениями могут быть ключи, при этом их значения являются hashrefs с ключевой информацией. Если хотите, сохраните значение конечной точки в своем hashref.

Ключ "Endpoints" в вашем JSON, похоже, не так много стоит. Но если вам это нужно, возможно, так как будут другие типы ключей, тогда у вас может быть значение другого hashref, которое будет содержать hashref с конечными значениями в качестве ключей.

Например

 
{ 
    "Endpoints": { 
     "1.1.1.1": { "client_ip": "3.4.5.6",  ... }, 
     "2.2.2.2": { "client_ip": "19.20.21.22", ... }, 
     ... 
    }, 
    "OtherKeys": { ... }, ... 
} 

Последние значения не должны заканчиваться запятой. См. JSON format.

Когда вы приносите это в Perl вы будете иметь вложенные hashrefs, как

$data = { 
    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_ip для них

my @endpoints = keys %{$data->{Endpoints}}; 
foreach my $ip (@endpoints) { 
    say $data->{Endpoints}{$ip}{client_ip}; 
} 

См Using References in perlref и this post полностью об этом. Также см. perlreftut и perldsc.

Мы можем проверить (см) всю структуру данных с Data::Dumper

use Data::Dumper; 
my $data = decode_json($json); 
print Dumper($data); 

Существует ряд других пакетов для работы с вложенными структурами данных.

Обратите внимание, что пакет JSON поставляется с encode_json и связанными с ним способами, поэтому вы можете создать этот файл программно. Это может помочь в правильном выборе формата и в будущем.

+0

Если я хочу получить client_ip конечной точки 1.1.1.1, как это сделать? – nims

+0

@nims Ах, правильно. Добавлено в ответ. Я также добавлю некоторые ссылки для обработки hashrefs. – zdim

+0

@nims Я добавил несколько ссылок для обработки hashrefs, первый для этого точного использования. Сообщите мне, если бизнес hashref является проблемой - это очень важно, чтобы без проблем использовать JSON. – zdim

 Смежные вопросы

  • Нет связанных вопросов^_^