Skip to content

Commit

Permalink
Add jpath, a cut(1) that uses JSONPath to describe fields to output.
Browse files Browse the repository at this point in the history
  • Loading branch information
rcaputo committed May 21, 2011
1 parent b0065f1 commit 3c84b44
Show file tree
Hide file tree
Showing 7 changed files with 129 additions and 10 deletions.
31 changes: 28 additions & 3 deletions README
Original file line number Diff line number Diff line change
Expand Up @@ -26,29 +26,54 @@ DESCRIPTION
{"network":"magnet","channel":"#poe"}
{"network":"magnet","channel":"#reflex"}

The jpath filter supports more complex expressions using JSON::Path’s
variant of JSONPath.

% curl −s 'http://api.duckduckgo.com/?q=poe&o=json' |
jpath −o '$..Topics.*.FirstURL' −o '$..Topics.*.Text' |
grep −i perl |
jmap −i col0 −o url −i col1 −o title |
json2yaml
−−−
title: Perl Object Environment, a library for event driven multitasking for the Perl programming language
url: http://duckduckgo.com/Perl_Object_Environment

DESIGN GOAL
Follow the UNIX convention of one record per line of text. This
ensures App::PipeFilter tools are compatible with many standard UNIX
filters. In the example above, jcut output is piped through sort(1)
and uniq(1) as one might expect.
filters. In the examples above, jcut and jpath output is piped through
sort(1), uniq(1) and grep(1).

PRO TIPS
JSON isn’t particularly concise, so put grep(1) and other filters that
eliminate objects as early as possible in pipelines.

SEE ALSO
jcut − Extract one or more named fields from JSON input.

jmap − Rename one or more named fields from JSON input.

jpath − Like jcut, but fields are described using JSON::Path’s variant
of JSONPath.

json2yaml − Convert JSON input records to YAML output records. Some
people may find YAML output to be more readable.

jsort − Sort JSON input on one or more key fields.

myswl2json − Convert mysql(1) batch output (−B) into JSON records.

http://json.org/

http://search.cpan.org/perldoc?JSON::Path

http://goessner.net/articles/JsonPath/

COPYRIGHT and LICENSE
App::PipeFilter is Copyright 2011 by Rocco Caputo. All rights are
reserved. App::PipeFilter is released under the same terms as Perl
itself.



perl v5.10.0 2011‐05‐20 App::PipeFilter(3)
perl v5.10.0 2011‐05‐21 App::PipeFilter(3)
6 changes: 3 additions & 3 deletions TODO.otl
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@
[_] 0% Document the libraries.
[_] 0% Document the executables.
[_] 0% Test dzil.ini.
[_] % Additional features
[_] % Allow -o to be JSON::Path descriptions.
This would be easy, except how are the results represented?
[X] 100% Additional features
[X] 100% Allow -o to be JSON::Path descriptions.
Implemented jpath that acts like jcut but using JSONPath.
5 changes: 5 additions & 0 deletions bin/jpath
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/perl

use App::PipeFilter::JsonPath;

App::PipeFilter::JsonPath->new_with_options()->run();
19 changes: 17 additions & 2 deletions eg/README
Original file line number Diff line number Diff line change
@@ -1,6 +1,21 @@
duckduckgo.json is a sample JSON response from:
curl 'http://api.duckduckgo.com/?q=poe&o=json' > duckduckgo.json
curl 'http://api.duckduckgo.com/?q=poe&o=json'

reddit.json is sample JSON from http://www.reddit.com/.json
reddit.json is sample JSON from:
curl http://www.reddit.com/.json

sample.json is just some tabular data I put together for testing.

delicious-urlinfo.json comes from:
curl -s http://feeds.delicious.com/v2/json/urlinfo/7b6cdc20ad985d4ddc547cd18a9e3998

*** Filtering Web Data with JSONPath

% curl -s 'http://api.duckduckgo.com/?q=poe&o=json' |
jpath -o '$..Topics.*.FirstURL' -o '$..Topics.*.Text' |
jmap -i col0 -o url -i col1 -o title |
grep -i perl |
json2yaml
---
title: Perl Object Environment, a library for event driven multitasking for the Perl programming language
url: http://duckduckgo.com/Perl_Object_Environment
1 change: 1 addition & 0 deletions eg/delicious-urlinfo.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[{"hash":"7b6cdc20ad985d4ddc547cd18a9e3998","title":"POE: Perl Object Environment","url":"http:\/\/poe.perl.org\/","total_posts":225,"top_tags":{"perl":204,"programming":104,"poe":100,"framework":73,"development":47,"network":40,"networking":26,"dev":22,"server":16,"software":15}}]
30 changes: 28 additions & 2 deletions lib/App/PipeFilter.pm
Original file line number Diff line number Diff line change
Expand Up @@ -24,26 +24,52 @@ objects rather than whitespace separated fields.
{"network":"magnet","channel":"#poe"}
{"network":"magnet","channel":"#reflex"}
The jpath filter supports more complex expressions using JSON::Path's
variant of JSONPath.
% curl -s 'http://api.duckduckgo.com/?q=poe&o=json' |
jpath -o '$..Topics.*.FirstURL' -o '$..Topics.*.Text' |
grep -i perl |
jmap -i col0 -o url -i col1 -o title |
json2yaml
---
title: Perl Object Environment, a library for event driven multitasking for the Perl programming language
url: http://duckduckgo.com/Perl_Object_Environment
=head1 DESIGN GOAL
Follow the UNIX convention of one record per line of text. This
ensures App::PipeFilter tools are compatible with many standard UNIX
filters. In the example above, jcut output is piped through sort(1)
and uniq(1) as one might expect.
filters. In the examples above, jcut and jpath output is piped
through sort(1), uniq(1) and grep(1).
=head1 PRO TIPS
JSON isn't particularly concise, so put grep(1) and other filters that
eliminate objects as early as possible in pipelines.
=head1 SEE ALSO
jcut - Extract one or more named fields from JSON input.
jmap - Rename one or more named fields from JSON input.
jpath - Like jcut, but fields are described using JSON::Path's
variant of JSONPath.
json2yaml - Convert JSON input records to YAML output records. Some
people may find YAML output to be more readable.
jsort - Sort JSON input on one or more key fields.
myswl2json - Convert mysql(1) batch output (-B) into JSON records.
http://json.org/
http://search.cpan.org/perldoc?JSON::Path
http://goessner.net/articles/JsonPath/
=head1 COPYRIGHT and LICENSE
App::PipeFilter is Copyright 2011 by Rocco Caputo. All rights are
Expand Down
47 changes: 47 additions & 0 deletions lib/App/PipeFilter/JsonPath.pm
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package App::PipeFilter::JsonPath;

use Moose;
extends 'App::PipeFilter::Generic::Json';

use JSON::Path;

has o => (
is => 'rw',
isa => 'ArrayRef',
default => sub { die "requires one or more -o flag" },
lazy => 1,
documentation => 'output fields (a subset of the input)',
);

has _o => (
is => 'rw',
isa => 'ArrayRef[JSON::Path]',
lazy => 1,
default => sub {
my $self = shift;
return [ map { JSON::Path->new($_) } @{$self->o()} ];
},
);

sub transform {
my $self = shift();

my @json_paths = @{$self->_o()};

my @output;

my $c = 0;
foreach my $json_path (@json_paths) {
my $r = 0;
foreach my $json_value ($json_path->values($_[0])) {
$output[$r++]{"col$c"} = $json_value;
}
++$c;
}

return @output;
}

1;

# vim: ts=2 sw=2 expandtab

0 comments on commit 3c84b44

Please sign in to comment.