0

想要从 json 文件中获取值:

例子:

{"ipaddr":"10.1.1.2","hostname":"host2","role":"http","status":"active"},
{"ipaddr":"10.1.1.3","hostname":"host3","role":"sql","status":"active"},
{"ipaddr":"10.1.1.4","hostname":"host4","role":"quad","status":"active"},

预期的:

10.1.1.2 host2 http active
10.1.1.3 host3 sql active
10.1.1.4 host4 quad active

我尝试:

grep -Po '(?<=ipaddr\")[^\"]+'

但是只能得到“:”,就像结果一样,当我开始得到一些东西时它只是一个。

4

5 回答 5

6

首先,输入字符串应该是有效的 JSON,所以数组元素需要在里面[]并且最后一个数组元素不应该有尾随逗号。

use strict;
use warnings;
use JSON;
my $s = q(
  [
    {"ipaddr":"10.1.1.2","hostname":"host2","role":"http","status":"active"},
    {"ipaddr":"10.1.1.3","hostname":"host3","role":"sql","status":"active"},
    {"ipaddr":"10.1.1.4","hostname":"host4","role":"quad","status":"active"}
  ]
);

my $aref = decode_json($s);
my @k = qw( ipaddr hostname role status );

print "@$_{@k}\n" for @$aref;

# or
local $" = "|";
print "@$_{@k}\n" for @$aref;

输出

10.1.1.2 host2 http active
10.1.1.3 host3 sql active
10.1.1.4 host4 quad active

10.1.1.2|host2|http|active
10.1.1.3|host3|sql|active
10.1.1.4|host4|quad|active
于 2013-09-20T12:38:34.417 回答
1
grep -Po ':"\K[^"]*' file

将打印出您需要的所有值。但是格式不是您所期望的,因为-o每个匹配项都会排成一行。你可以尝试的是:

 grep -Po ':"\K[^"]*' file|xargs -n4 

测试:

kent$  grep -Po ':"\K[^"]*' f|axrgs -n4           
10.1.1.2 host2 http active
10.1.1.3 host3 sql active
10.1.1.4 host4 quad active

使用awk您可以一次完成提取和格式化:

awk -F'":"|","|"}' '{print $2,$4,$6,$8}' file

如果您有很多字段,您可以编写一个循环,只需打印带有 EVEN idx 的字段。

用你的文件测试:

kent$  awk -F'":"|","|"}' '{print $2,$4,$6,$8}' f
10.1.1.2 host2 http active
10.1.1.3 host3 sql active
10.1.1.4 host4 quad active
于 2013-09-20T12:25:31.590 回答
1

由于from_json返回对哈希的引用,因此您可以获取该哈希的“切片”并返回这些字段中的值列表。对于您在此处显示的每一行,您可以执行以下操作:

s/,\s*$//;join( "\t", @{ from_json( $line) }{ qw<ipaddr hostname role status> } );

当然,这必须通过导入JSON库来完成。所以在命令行上它看起来像这样:

perl -MJSON -ne 's/,\s*$//;print join( "\t", @{ from_json($_) }{ qw<ipaddr hostname role status> } ), "\n"'
于 2013-09-20T12:26:11.817 回答
1

使用awk

awk -F\" '{print $4,$8,$12,$16}' file
10.1.1.2 host2 http active
10.1.1.3 host3 sql active
10.1.1.4 host4 quad active

其他变体

awk -F\" '{for (i=4;i<=16;i+=4) printf "%s ",$i;print ""}' file
于 2013-09-20T12:38:31.777 回答
1
perl -lne 'push @a,/:\"([^\"]*)\"/g;print "@a";undef @a' your_file

测试:

> cat temp
{"ipaddr":"10.1.1.2","hostname":"host2","role":"http","status":"active"},
{"ipaddr":"10.1.1.3","hostname":"host3","role":"sql","status":"active"},
{"ipaddr":"10.1.1.4","hostname":"host4","role":"quad","status":"active"},
> perl -lne 'push @a,/:\"([^\"]*)\"/g;print "@a";undef @a' temp
10.1.1.2 host2 http active
10.1.1.3 host3 sql active
10.1.1.4 host4 quad active
> 
于 2013-09-20T12:54:03.513 回答