Linux

如何在 Perl 中迭代 JSON 對象集合(不是數組)?

  • December 17, 2019

我正在學習 Perl。當對象包含在數組中時,我已經能夠成功地遍歷 JSON 集合。但是,我無法理解如何處理對像不在數組中並且具有事先不知道的0y7vfr1234隨機標識符(例如)的 JSON 數據。這是我嘗試讀取、更新並保存回文件的結構的一些範例數據。

{
   "0y7vfr1234": {
       "username": "user1@example.com",
       "password": "some-random-password123",
       "uri": "ww1.example.com",
       "index": 14
   },
   "v2rbz1568": {
       "username": "user3@example.com",
       "password": "some-random-password125",
       "uri": "ww3.example.com",
       "index": 29
   },
   "0zjk1156": {
       "username": "user2@example.com",
       "password": "some-random-password124",
       "uri": "ww2.example.com",
       "index": 38
   }
}

如果這些對像都在一個數組中,我會這樣做:

#!/usr/bin/perl

use lib qw(..);
use JSON;
binmode STDOUT, ":utf8";
use utf8;
use strict;
use warnings;

my $filename1 = 'input.json';
my $filename2 = 'serverlist.txt';

my $json_text = do {
open(my $json_fh, "<:encoding(UTF-8)", $filename1)
   or die("Can't open \$filename1\": $!\n");
local $/;
<$json_fh>
};

open my $server_list, '<', $filename2 or die "Can't open $filename2: $!";
my @server_list = <$server_list>;
close $server_list or die "Can't close $server_list: $!";

my $json = JSON->new;
my $data = $json->decode($json_text);

my $aref = $data->{the_array_name};

for my $setting (@$aref) {
   if (length $setting->{uri}) { #no warnings
       $setting->{uri} =~ m/^ww(\d+)\.example.com/;
       my $server_number = $1;
       print "checking $server_number ... \n";
       if (grep{/$setting->{uri}/} @server_list) {
           print "server number is:  $server_number\n";
       } else {
           # 1. iterate through the sorted list
           foreach (@server_list)
           {
               $_ =~ m/^ww(\d+)\.example.com/;
               my $new_num = $1;
               # 2. find the next match in order
               if ( $new_num > $server_number ) {
                   print "Found it: new server number $new_num is greater than $server_number\n";
                   # TODO 3. check that it does not exist in $data->{the_array_name};

                   # 4. replace $setting->{uri} with new value
                   my $new_server = $_;
                   $new_server =~ s/\s+$//;
                   $setting->{uri} = $new_server;
                   last;
               }
           }
       }
   }
}

# 5. save JSON as a file to disk.
my $filename3 = 'output.json';
open my $proxy_settings, '>', $filename3 or die "Can't open $filename3: $!";
print $proxy_settings encode_json($data);
close $proxy_settings or die "Can't close $proxy_settings: $!";

這是我寫的第一個 Perl。我還沒有 100% 理解它的每一行。(例如:)binmode STDOUT, ":utf8";。我確信它遠非最佳,我會繼續努力。我的問題是,如何修改它以使用上面顯示的 JSON 結構?

我在 Linux 上使用 perl 5,版本 30。

像這樣 :

#!/usr/bin/perl
use JSON;
use utf8;
use strict; use warnings;

my $data = '{
 "0y7vfr1234": {
   "username": "user1@example.com",
   "password": "some-random-password123",
   "uri": "ww1.example.com",
   "index": 14
 },
 "v2rbz1568": {
   "username": "user3@example.com",
   "password": "some-random-password125",
   "uri": "ww3.example.com",
   "index": 29
 },
 "0zjk1156": {
   "username": "user2@example.com",
   "password": "some-random-password124",
   "uri": "ww2.example.com",
   "index": 38
 }
}';

my $json = decode_json $data;

foreach my $key (keys %$json) {
   print "$key\n";
}

print "$json->{v2rbz1568}->{username}\n";

 輸出

v2rbz1568
0y7vfr1234
0zjk1156
user3@example.com

引用自:https://unix.stackexchange.com/questions/557609