JSON One-Liners
2026-04-13
JSON is the universal data exchange format. Raku can parse and manipulate JSON from the command line using the built-in JSON::Fast module (included with Rakudo), making it a handy alternative to jq for quick data extraction.
Reading JSON
Parse a JSON file and pretty-print it:
raku -MJSON::Fast -e 'say to-json(from-json(slurp("data.json")), :pretty)'
Parse JSON from STDIN:
echo '{"name":"Alice","age":30}' | raku -MJSON::Fast -e 'say from-json($*IN.slurp).raku'
Extracting Fields
Get a single field from a JSON object:
echo '{"name":"Alice","age":30}' | raku -MJSON::Fast -e 'say from-json($*IN.slurp)<name>'
Get a nested field:
echo '{"user":{"name":"Alice","address":{"city":"Toronto"}}}' | \
raku -MJSON::Fast -e 'say from-json($*IN.slurp)<user><address><city>'
Working with Arrays
Print each element of a JSON array:
echo '[1,2,3,4,5]' | raku -MJSON::Fast -e '.say for from-json($*IN.slurp).list'
Get a specific index:
echo '["alpha","beta","gamma"]' | raku -MJSON::Fast -e 'say from-json($*IN.slurp)[1]'
Count elements:
echo '[1,2,3,4,5]' | raku -MJSON::Fast -e 'say from-json($*IN.slurp).elems'
Filtering Array Objects
Given an array of objects, filter by a field:
cat <<'EOF' | raku -MJSON::Fast -e '
my @data = from-json($*IN.slurp).list;
.say for @data.grep(*<active>).map(*<name>);
'
[{"name":"Alice","active":true},{"name":"Bob","active":false},{"name":"Carol","active":true}]
EOF
Output:
Extracting a Field from Each Object
Get all names from an array of objects:
raku -MJSON::Fast -e '
my @data = from-json(slurp("users.json")).list;
.say for @data.map(*<name>);
'
Sorting JSON Arrays
Sort objects by a field:
raku -MJSON::Fast -e '
my @data = from-json(slurp("users.json")).list;
say to-json(@data.sort(*<age>), :pretty);
'
Sort descending:
raku -MJSON::Fast -e '
my @data = from-json(slurp("users.json")).list;
say to-json(@data.sort(-*<age>), :pretty);
'
Aggregating Data
Sum a numeric field:
raku -MJSON::Fast -e '
my @items = from-json(slurp("orders.json")).list;
say "Total: " ~ @items.map(*<amount>).sum;
'
Average:
raku -MJSON::Fast -e '
my @items = from-json(slurp("scores.json")).list;
my @vals = @items.map(*<score>);
say "Average: {(@vals.sum / @vals.elems).round(0.01)}";
'
Group and count:
raku -MJSON::Fast -e '
my @data = from-json(slurp("events.json")).list;
my %groups;
%groups{$_<type>}++ for @data;
say "$_.key(): $_.value()" for %groups.sort(-*.value);
'
Transforming JSON
Add a field to each object:
raku -MJSON::Fast -e '
my @data = from-json(slurp("users.json")).list;
my @enhanced = @data.map({ %( |$_, status => "processed") });
say to-json(@enhanced, :pretty);
'
Remove a field:
raku -MJSON::Fast -e '
my @data = from-json(slurp("users.json")).list;
my @clean = @data.map({ my %h = $_.Hash; %h<password>:delete; %h });
say to-json(@clean, :pretty);
'
Rename a field:
raku -MJSON::Fast -e '
my @data = from-json(slurp("data.json")).list;
my @renamed = @data.map({
my %h = $_.Hash;
%h<full_name> = %h<name>:delete;
%h
});
say to-json(@renamed, :pretty);
'
Converting JSON to CSV
raku -MJSON::Fast -e '
my @data = from-json(slurp("users.json")).list;
my @keys = @data[0].keys.sort;
say @keys.join(",");
for @data -> %row {
say @keys.map({ %row{$_} // "" }).join(",");
}
'
Converting CSV to JSON
raku -MJSON::Fast -e '
my @lines = "data.csv".IO.lines;
my @headers = @lines.shift.split(",");
my @data = @lines.map(-> $line {
my @vals = $line.split(",");
my %row;
for @headers.kv -> $i, $h { %row{$h} = @vals[$i] // "" }
%row
});
say to-json(@data, :pretty);
'
Merging JSON Files
Combine two JSON arrays:
raku -MJSON::Fast -e '
my @a = from-json(slurp("file1.json")).list;
my @b = from-json(slurp("file2.json")).list;
say to-json([|@a, |@b], :pretty);
'
Merge two JSON objects (shallow):
raku -MJSON::Fast -e '
my %a = from-json(slurp("defaults.json")).Hash;
my %b = from-json(slurp("overrides.json")).Hash;
say to-json(%( |%a, |%b ), :pretty);
'
Validating JSON
Check if a string is valid JSON:
echo '{"valid": true}' | raku -MJSON::Fast -e '
try {
from-json($*IN.slurp);
say "Valid JSON";
CATCH { default { say "Invalid JSON: {.message}" } }
}
'
Piping with Other Tools
Combine with curl to process API responses:
curl -s https://httpbin.org/get | raku -MJSON::Fast -e '
my %data = from-json($*IN.slurp).Hash;
say "Origin: {%data<origin>}";
say "Headers:";
for %data<headers>.sort -> $h {
say " {$h.key}: {$h.value}";
}
'
Pretty vs Compact Output
raku -MJSON::Fast -e 'say to-json(from-json(slurp("data.json")), :pretty)'
raku -MJSON::Fast -e 'say to-json(from-json(slurp("data.json")))'
raku -MJSON::Fast -e 'say to-json(from-json(slurp("data.json")), :pretty, :sorted-keys)'
These one-liners make Raku a viable command-line JSON processor. For quick extraction and transformation tasks, they are often easier to write than the equivalent jq expressions, especially when you need to combine JSON processing with other logic.