-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathjf
executable file
·65 lines (56 loc) · 1.23 KB
/
jf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#!/usr/bin/perl
use warnings;
use strict;
use JSON;
use Getopt::Std;
my %opts;
getopts('pl', \%opts);
unless ($opts{l}) {
$/ = undef; # slurp whole files at a time
}
if (scalar(@ARGV) < 1) { usage() }
my @fields;
while ((my $field = shift)) {
if ($field eq '--') { last; }
push @fields, $field;
}
my $fieldtree = {};
for my $field (@fields) {
my @nodes = split '/', $field;
my $tree = $fieldtree;
for my $node (@nodes) {
if (!exists($tree->{$node})) {
$tree->{$node} = {};
}
$tree = $tree->{$node};
}
}
binmode STDOUT, ":utf8";
my $json_handler = JSON->new;
while (<>) {
my $wanted = descend($json_handler->decode($_), $fieldtree);
if ($opts{'p'}) {
print $json_handler->pretty->encode($wanted)."\n";
} else {
print $json_handler->encode($wanted)."\n";
}
}
sub descend {
(my $json, my $fields) = @_;
if (ref($json) =~ /ARRAY/) {
return [ map { descend($_, $fields) } @$json ];
} elsif (scalar(keys %$fields) > 0) {
my %ret;
while ((my $field, my $subtree) = each %$fields) {
$ret{$field} = descend($json->{$field}, $subtree);
}
return \%ret;
} else {
return $json;
}
}
sub usage {
print "Usage: $0 field1 field2 .. -- file1 file2 ..\n";
print "or cat file1 file2 .. | $0 field1 field2 ..\n";
exit 2;
}