我已经创建了一个脚本,从各种外部来源获得一些信息,然后结果应该是在json格式.有很多数据,我将所有内容都推入一个循环中的数组中,然后在完成所有操作后打印json数组,这是脚本的循环部分的摘录:

#!/usr/bin/perl
use JSON -convert_blessed_universally;
use strict;
use warnings;
my @json_arr;
my @servers = ("SERVER1", "SERVER2");
my @details = ("SERVER1,10.1.2.3,Suse Linux",
               "SERVER2,10.1.2.4,Windows 10",
               "SERVER3,10.1.2.5,Windows XP");
my $json = JSON->new->convert_blessed;

foreach my $server(@servers) {
    foreach (@details) {
        my @detail = split(',',$_);
        if ($server eq $detail[0]) {
          push @json_arr, {name => "$server", ip => "$detail[1]", os => "$detail[2]"};
      }
   }
}
my $result = $json->encode(\@json_arr);
print $result;

这会产生以下输出:

[
   {
      "name" : "SERVER1",
      "ip" : "10.1.2.3",
      "os" : "Suse Linux",
   },
   {
      "name" : "SERVER2",
      "ip" : "10.1.2.4",
      "os" : "Widows 10"
   }
]

还有一张截图:

enter image description here

但是,我正在try 通过设置一个关键元素并将附加数据作为设备名称的子项来完成此操作,即:

{
  "instance" : [
    {
      "SERVER1" : {
        "ip" : "10.1.2.3",
        "os" : "Suse Linux"
      },
      "SERVER2" : {
         "ip" : "10.1.2.4",
         "os" : "Windows 10"
      }
    }
  ]
}

所以我try 了一些方法,包括下面这样的东西,然后按数组,但我得到了有趣的结果,只是没有得到想要的结果.

my $json = '{
   "instance" : [
       $server => {
          ip => "$detail[0]",
          os => "$detail[1]"
       }
   ] 
}';
push @json_arr, $json;

推荐答案

只需稍作调整即可

use warnings;
use strict;
use feature 'say';

use Data::Dumper;
use JSON::XS;

...

my @json_ary;

foreach my $server (@servers) {
    foreach (@details) {
        my @detail = split /,/; 
        if ($server eq $detail[0]) {
            #push @json_ary, {name => "$server", ip => "$detail[1]" ...
            push @json_ary, 
                { $server => { ip => $detail[1], os => $detail[2] } } 
        }
    }   
}

print Dumper \@json_ary;

# Encode `{ instance => \@json_ary }` for the desired output
my $json = JSON->new->convert_blessed;
my $result = $json->pretty->encode( { instance => \@json_ary } );

say $result;

几点注意事项

  • 不需要用引号将变量括起来,因为无论如何都会对它们求值("$detail[0]"-->;$detail[0]等)

  • 不需要在散列键两边加引号,这是语法上的便利:key => 'value'就可以了(如果值是一个变量,则只有key => $var).也就是说,只要密钥名称中没有空格.

  • 美化打印现有JSON字符串的一种方法是:

    print JSON::XS->new->ascii->pretty->encode(decode_json $json_str);
    

可能会有一个关于是否需要围绕每个服务器条目(JSON对象)的hashref的问题;在讨论之后的一条 comments 中证实了这一点,所以我接受了它.

但是,如果输出只需要在数组中包含服务器条目的hashref(而不是每个服务器的hashref数组),则可以修改问题中的代码以

my %server_details;

foreach my $server (@servers) {
    foreach (@details) {
        my @detail = split /,/; 
        if ($server eq $detail[0]) {
            $server_details{$server} = { ip => $detail[1], os => $detail[2] }
        }
    }   
}

现在,该散列具有所有服务器的详细信息,并且可以用密钥instance编码.那么我就不清楚总体 struct 应该是什么;一个 Select 是:

my $result = JSON->pretty->encode( { instance => [ \%server_details ] }  );

Json相关问答推荐

jq不会为空输入返回非零

手动解开没有可编码的SON- Swift

使用WSO2 JsonTransform Mediator对空值执行JsonExceptionUndeletedOperationException

使用动态和可变JSON的图表多条

在Ansible中从json中提取特定数据

序列化从/到空值

Jolt:数组中两个字符串的连接

PowerShell - 将 json 添加到文件内容

JOLT 获取带有动态键的数组

我无法将来自 API 的数据显示到 FlatList 中,但我在 console.log 中看到了它.问题是什么?

用powershell条件解析json文件的数组对象

ORA-01422: 精确提取返回的行数超过了与 json 对象组合的请求数

如果 JSON 对象包含列表中的子字符串,则丢弃它们

TSQL FOR JSON 嵌套值

编写 JSON 日志(log)文件的格式?

使用 Spring 和 JsonTypeInfo 注释将 JSON 反序列化为多态对象模型

使用 jq,将对象数组转换为具有命名键的对象

如何使用 LWP 发出 JSON POST 请求?

PHP json_encode json_decode UTF-8

如何遍历 JSON 中的条目?