2016-09-21 4 views
2

Ich habe ein Testskript geschrieben, um bestimmte Funktionen auszuführen. Skript funktioniert wie erwartet. Zurzeit werden die zum Ausführen des Skripts erforderlichen Argumente über die Befehlszeile unter Verwendung von Getopt::Long übergeben. Ich möchte die Befehlszeilenargumente in eine JSON-Datei verschieben. Die Endpoint IP wird weiterhin als Befehlszeilenarg übergeben. Ich möchte, dass der Endpunkt IP als Schlüssel fungiert. Wenn der Endpunkt beispielsweise 1.1.1.1 lautet, möchte ich den Port client_ip, client_interface_ip, originip, .... abrufen, der unter der Endpunkt-ID 1.1.1.1 in der unten genannten json-Konfigurationsdatei aufgeführt ist. Wie mache ich das ?Parse json Array mit Perl

aktuelle Version des Skripts:

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-Datei für Argumente:

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

Antwort

2

Die erste Frage bezieht sich auf ein geeignetes Design für die JSON-Datei. Hashes können hier gut funktionieren, während das Arrayref überhaupt nicht benötigt wird. Die Endpunktwerte können die Schlüssel sein, wobei ihre Werte Hash-Referenzen mit schlüsselbezogenen Informationen sind. Behalten Sie den Endpunktwert auch in seiner hashref, wenn Sie möchten.

Der Schlüssel "Endpoints" in Ihrem JSON scheint nicht viel zu tun, wie es aussieht. Aber wenn Sie es brauchen, vielleicht weil es andere Arten von Schlüsseln gibt, dann könnten Sie für seinen Wert einen anderen Hashref haben, der den Hashref mit Endpunktwerten als Schlüssel enthält.

Zum Beispiel

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

Die letzten Werte sollten nicht mit Komma beenden. Siehe JSON format.

Wenn Sie dies in Perl bringen werden Sie verschachtelte hashrefs haben, wie

$data = { 
    Endpoints => { 
     1.1.1.1 => { client_ip => '3.4.5.6',  ... }, 
     2.2.2.2 => { client_ip => '19.20.21.22', ... }, 
    }, 
    OtherKeys => { ... }, 
}; 

Dann werden die Werte

my $client_ip = $data->{Endpoints}{'1.1.1.1'}{client_ip}; 

Zum Beispiel einfach als

abgerufen, retreive alle Endpunkte und Liste client_ip für sie

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

Siehe Using References in perlref und 01.236.ist völlig darüber. Siehe auch perlreftut und perldsc.

Wir untersuchen (sehen) die gesamte Datenstruktur mit Data::Dumper

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

Es gibt eine Reihe von anderen Paketen ist mit verschachtelten Datenstrukturen für die Arbeit.

Beachten Sie, dass das Paket JSON mit encode_json und verwandten Methoden geliefert wird, so dass Sie diese Datei programmgesteuert erstellen können. Dies kann dazu beitragen, dass das Format in Zukunft korrekt und wartungsfreundlich ist.

+0

Wenn ich die client_ip von Endpunkt 1.1.1.1 erhalten möchte, wie mache ich das? – nims

+0

@nims Ah, richtig. Zu der Antwort hinzugefügt. Ich werde einige Referenzen hinzufügen, um auch die HashRefs zu behandeln. – zdim

+0

@nims Ich habe einige Referenzen für die Behandlung von Hashrefs hinzugefügt, die erste für diese genaue Verwendung. Lassen Sie mich wissen, ob das Problem mit der Hash-Funktion ein Problem ist - das ist wichtig, um JSON ohne Probleme nutzen zu können. – zdim