/jql

A JSON Query Language CLI tool

Primary LanguageRustApache License 2.0Apache-2.0

jql


GitHub Workflow Status Crates.io Docs.rs Docs.rs

jql is a JSON Query Language tool built with Rust 🦀.

Pronounce it as jackal 🐺.

📜 Philosophy

  • ⚡Be fast
  • 🪶 Stay lightweight
  • 🎮 Keep its features as simple as possible
  • 🧠 Avoid redundancy
  • 💡 Provide meaningful error messages
  • 🍰 Eat JSON as input, process, output JSON back

🚀 Installation

Alpine Linux

The package is maintained by @jirutka.

apk add jql

Archlinux

The AUR package is maintained by @barklan.

yay -S jql

Cargo

cargo install jql

Cargo Binstall

cargo binstall jql

Fedora

dnf install jql

FreeBSD

pkg install jql

Homebrew

brew install jql

Nix

nix-env -i jql

openSUSE

zypper install jql

Manual installation from GitHub

Compiled binary versions are automatically uploaded to GitHub when a new release is made. You can install jql manually by downloading a release.

🛠️ Usage

To make a selection from a JSON input, jql expects a query as a sequence of tokens.

To be fully compliant with the JSON format, jql always expect key selectors to be double-quoted, see The JavaScript Object Notation (JSON) Data Interchange Format.

{
  ".valid": 1337,
  "": "yeah!",
  "\"": "yup, valid too!"
}

Consequently, to be shell compliant, a query must be either enclosed by single quotation marks or every inner double quotation mark must be escaped.

Separators

Group separator

Group separators build up an array from sub-queries.

JSON input

{ "a": 1, "b": 2, "c": 3 }

Query

'"a","b","c"'

JSON output

[1, 2, 3]

Selectors

Arrays

Array index selector

Indexes can be used in arbitrary order.

JSON input

[1, 2, 3]

Query

'[2,1]'

JSON output

[3, 2]
Array range selector

Range can be in natural order [0:2], reversed [2:0], without lower [:2] or upper bound [0:].

JSON input

[1, 2, 3]

Query

'[2:1]'

JSON output

[3, 2]
Lens selector

Lens can be a combination of one or more selectors with or an optional value, a value being any of boolean | null | number | string.

JSON input

[
  { "a": 1, "b": { "d": 2 } },
  { "a": 2, "b": "some" },
  { "a": 2, "b": { "d": null } },
  { "a": 2, "b": true },
  { "c": 3, "b": 4 }
]

Query

'|={"b""d"=2, "c"}'

JSON output

[
  { "a": 1, "b": { "d": 2 } },
  { "c": 3, "b": 4 }
]

Objects

Key selector

Any valid JSON key can be used.

JSON input

{ "a": 1, "b": 2, "c": 3 }

Query

'"c"'

JSON output

3
Multi key selector

Keys can be used in arbitrary order.

JSON input

{ "a": 1, "b": 2, "c": 3 }

Query

'{"c","a"}'

JSON output

{ "c": 3, "a": 1 }
Object index selector

Indexes can be used in arbitrary order.

JSON input

{ "a": 1, "b": 2, "c": 3 }

Query

'{2,0}'

JSON output

{ "c": 3, "a": 1 }
Object range selector

Range can be in natural order {0:2}, reversed {2:0}, without lower {:2} or upper bound {0:}.

JSON input

{ "a": 1, "b": 2, "c": 3 }

Query

'{2:1}'

JSON output

{ "c": 3, "b": 2 }

Operators

Flatten operator

Flattens arrays and objects.

JSON input

[[[[[[[[[[[[[[{ "a": 1 }]]]]]]]]]]]]], [[[[[{ "b": 2 }]]]], { "c": 3 }], null]

Query

'..'

JSON output

[{ "a": 1 }, { "b": 2 }, { "c": 3 }, null]

JSON input

{ "a": { "c": false }, "b": { "d": { "e": { "f": 1, "g": { "h": 2 } } } } }

Query

'..'

JSON output

{
  "a.c": false,
  "b.d.e.f": 1,
  "b.d.e.g.h": 2
}
Keys operator

Returns the keys of an object or the indices of an array. Other primitives are returned as is.

JSON input

{ "a": 1, "b": 2, "c": 3 }

Query

'@'

JSON output

["a", "b", "c"]
Pipe in operator

Applies the next tokens in parallel on each element of an array.

JSON input

{ "a": [{ "b": { "c": 1 } }, { "b": { "c": 2 } }] }

Query

'"a"|>"b""c"'

JSON output

[1, 2]
Pipe out operator

Stops the parallelization initiated by the pipe in operator.

JSON input

{ "a": [{ "b": { "c": 1 } }, { "b": { "c": 2 } }] }

Query

'"a"|>"b""c"<|[1]'

JSON output

2
Truncate operator

Maps the output into simple JSON primitives boolean | null | number | string | [] | {}.

JSON input

{ "a": [1, 2, 3] }

Query

'"a"!'

JSON output

[]

💻 Shell integration

How to save the output

jql '"a"' input.json > output.json

How to read from stdin

cat test.json | jql '"a"'

Available flags

Inline the JSON output

By default, the output is pretty printed in a more human-readable way, this can be disabled.

-i, --inline

Read the query from file

The command will read the provided query from a file instead of the stdin.

-q, --query <FILE>

Write to stdout without JSON double-quotes

This can be useful to drop the double-quotes surrounding a string primitive.

-r, --raw-string

Read a stream of JSON data line by line

This flag is only about reading processing any JSON output streamed line by line (e.g. Docker logs with the --follow flag). This is not an option to read an incomplete streamed content (e.g. a very large input).

-s, --stream

Validate the JSON data

The command will return a matching exit code based on the validity of the JSON content or file provided.

-v, --validate

Print help

-h, --help

Print version

-V, --version

Help

jql -h
jql --help

🦀 Workspace

This project is composed of following crates:

Development

Some commands are available as a justfile at the root of the workspace (testing / fuzzing).

Prerequisites

Commands

just --list

⚠️ Non-goal

There's no plan to align jql with jq or any other similar tool.

⚡ Performance

Some benchmarks comparing a set of similar functionalities provided by this tool and jq are available here.

📔 Licenses