문제

Want to get the values from json files:

Example:

{"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"},

Expected:

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

I try with:

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

But was able to get only ":", like result and it's only one when I start to get something.

도움이 되었습니까?

해결책 2

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

will print out all values that you need. but the format is not what you are expecting, because of the -o each matching will sit in one line. what you could try is:

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

test:

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

with awk you could do extracting and formatting in one shot:

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

if you have many fields, you could write a loop, just print the fields with EVEN idx.

test with your file:

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

다른 팁

First, input string should be valid JSON, so array elements need to be inside [] and last array element should not have trailing comma.

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;

output

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

Using 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

Other variation

awk -F\" '{for (i=4;i<=16;i+=4) printf "%s ",$i;print ""}' file
perl -lne 'push @a,/:\"([^\"]*)\"/g;print "@a";undef @a' your_file

Tested:

> 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
> 

Since from_json returns a reference to a hash, you can take a "slice" of that hash and return a list of values in those fields. For each line that you present here, you could do the following:

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

Of course this would have to be done importing the JSON library. So on the command line it would look like this:

perl -MJSON -ne 's/,\s*$//;print join( "\t", @{ from_json($_) }{ qw<ipaddr hostname role status> } ), "\n"'
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top