AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / unix / 问题 / 557746
Accepted
BugBuddy
BugBuddy
Asked: 2019-12-18 12:59:32 +0800 CST2019-12-18 12:59:32 +0800 CST 2019-12-18 12:59:32 +0800 CST

Perl - 不是 HASH 引用或不能使用字符串(“...”)作为 HASH 引用,而使用“严格引用”

  • 772

我正在学习 Perl。我可以使用示例数据使用这样的 Perl 哈希数据结构来迭代 JSON 集合。但是,实际数据包含一些导致错误Not a HASH reference或Can't use string ("...") as a HASH ref while "strict refs" in use.

这是给我带来麻烦的问题数据的简化示例:

{
    "0y7vfr1234": {
        "username": "[email protected]",
        "password": "some-random-password123",
        "uri": "ww1.example.com",
        "index": 14
    },
    "v2rbz1568": {
        "username": "[email protected]",
        "password": "some-random-password125",
        "uri": "ww3.example.com",
        "index": 29
    },
    "active": "0y7vfr1234",
    "0zjk1156": {
        "username": "[email protected]",
        "password": "some-random-password124",
        "uri": "ww2.example.com",
        "index": 38
    },
    "logging": {
        "active": true
    }
}

我只关心具有uri. 我想跳过其他的。我该怎么做?

在尝试了许多不起作用的事情(并且只会导致新的或不同的错误)之后,这就是我最终解决错误的方法。但是,我认为有比使用ref().

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

my $data = '{
        "0y7vfr1234": {
            "username": "[email protected]",
            "password": "some-random-password123",
            "uri": "ww1.example.com",
            "index": 14
        },
        "v2rbz1568": {
            "username": "[email protected]",
            "password": "some-random-password125",
            "uri": "ww3.example.com",
            "index": 29
        },
        "active": "0y7vfr1234",
        "0zjk1156": {
            "username": "[email protected]",
            "password": "some-random-password124",
            "uri": "ww2.example.com",
            "index": 38
        },
        "logging": {
            "active": true
        }
    }';

my $json = decode_json($data);

foreach my $key (keys %$json) {

    if ( ref( $json->{$key} ) !~ m/HASH/ ) {
            print "[" . ref( $json->{$key} ) . "]: skipping\n";
            next;
    }

    if ( ! exists $json->{$key}->{uri} ) {
        print "Not a server. It's type is:  [" . ref($json->{$key}) . "]\n";
        print "Without curly braces: $json->$key\n";
        print Dumper($json->{$key});
        print "With curly braces: $json->{$key}\n";
        next;
    }

    print "checking $json->{$key}->{uri}\n";
    # do some other stuff
}

代码或多或少按原样工作,但我对它不满意......或者我对它的理解。

我的问题是:

  1. 什么是迭代像我的 JSON 这样的“混合”数据而不遇到错误的正确方法?
  2. 显示有关我跳过的元素的一些信息的好方法是什么?我在代码中尝试了各种东西(数据转储器、不带花括号的打印等),但没有一个令人满意。有没有更好的方法可以显示有关已跳过内容的信息(当然不会导致错误)?
  3. 为什么上面的代码$json->{$key}->{uri}在没有这样的箭头的情况下也能工作:$json->{$key}{uri}?

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

linux perl
  • 1 1 个回答
  • 4224 Views

1 个回答

  • Voted
  1. Best Answer
    Gilles Quenot
    2019-12-18T13:38:02+08:002019-12-18T13:38:02+08:00

    像这样:

    #!/usr/bin/perl   
    use JSON; use utf8;
    use strict; use warnings;
    
    my $data = '{
            "0y7vfr1234": {
                "username": "[email protected]",
                "password": "some-random-password123",
                "uri": "ww1.example.com",
                "index": 14
            },
            "v2rbz1568": {
                "username": "[email protected]",
                "password": "some-random-password125",
                "uri": "ww3.example.com",
                "index": 29
            },
            "active": "0y7vfr1234",
            "0zjk1156": {
                "username": "[email protected]",
                "password": "some-random-password124",
                "uri": "ww2.example.com",
                "index": 38
            },
            "logging": {
                "active": true
            }
    }';   
    my $json = decode_json($data);
    while (my ($key, $value) = each(%$json)) {
        next unless ref $value;            # skip if $value isn't a ref
        next if scalar (keys %$value) < 2;  # skip if the numbers of HASH keys < 2
        print "$value->{uri}\n";
    }
    
    • 1

相关问题

  • 有没有办法让 ls 只显示某些目录的隐藏文件?

  • 使用键盘快捷键启动/停止 systemd 服务 [关闭]

  • 需要一些系统调用

  • astyle 不会更改源文件格式

  • 通过标签将根文件系统传递给linux内核

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    模块 i915 可能缺少固件 /lib/firmware/i915/*

    • 3 个回答
  • Marko Smith

    无法获取 jessie backports 存储库

    • 4 个回答
  • Marko Smith

    如何将 GPG 私钥和公钥导出到文件

    • 4 个回答
  • Marko Smith

    我们如何运行存储在变量中的命令?

    • 5 个回答
  • Marko Smith

    如何配置 systemd-resolved 和 systemd-networkd 以使用本地 DNS 服务器来解析本地域和远程 DNS 服务器来解析远程域?

    • 3 个回答
  • Marko Smith

    dist-upgrade 后 Kali Linux 中的 apt-get update 错误 [重复]

    • 2 个回答
  • Marko Smith

    如何从 systemctl 服务日志中查看最新的 x 行

    • 5 个回答
  • Marko Smith

    Nano - 跳转到文件末尾

    • 8 个回答
  • Marko Smith

    grub 错误:你需要先加载内核

    • 4 个回答
  • Marko Smith

    如何下载软件包而不是使用 apt-get 命令安装它?

    • 7 个回答
  • Martin Hope
    user12345 无法获取 jessie backports 存储库 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl 为什么大多数 systemd 示例都包含 WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky 如何将 GPG 私钥和公钥导出到文件 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll systemctl 状态显示:“状态:降级” 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim 我们如何运行存储在变量中的命令? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S 为什么 /dev/null 是一个文件?为什么它的功能不作为一个简单的程序来实现? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 如何从 systemctl 服务日志中查看最新的 x 行 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - 跳转到文件末尾 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla 为什么真假这么大? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis 在一个巨大的(70GB)、一行、文本文件中替换字符串 2017-12-30 06:58:33 +0800 CST

热门标签

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve