Crates.io | lq |
lib.rs | lq |
version | 0.15.0 |
created_at | 2024-10-28 19:41:29.771345+00 |
updated_at | 2025-05-08 22:18:53.89022+00 |
description | low overhead yq/tq/jq cli |
homepage | |
repository | https://github.com/clux/lq |
max_upload_size | |
id | 1425987 |
size | 82,825 |
A lightweight and portable jq style cli for doing jq queries/filters/maps/transforms on YAML/TOML/JSON documents by converting to JSON and passing data to jq
. Output is raw jq
output which can optionally be mapped to TOML or YAML.
Via cargo:
cargo install lq
or download a prebuilt from releases either manually, or via binstall:
cargo binstall lq
Note: Requires jq
.
jq
usage on any input format (yaml/toml/json) by going through json and jqjq
's cli interface (only some extra input/output format controlling flags)jq
output formatters such as -c
, -r
, and -j
(compact, raw, joined output resp)-y
(YAML out) or -t
(TOML out), -T
(TOML in), -J
(JSON in)yq
named/linked to lq
)jq
(not standalone - for now)Use as jq either via stdin:
$ lq '.[3].kind' -r < test/deploy.yaml
Service
$ lq -y '.[3].metadata' < test/deploy.yaml
labels:
app: controller
name: controller
namespace: default
or from a file arg (at the end):
$ lq '.[3].kind' -r test/deploy.yaml
$ lq -y '.[3].metadata' test/deploy.yaml
Infers input format from extension, or set explicitly via -T
or --input=toml
.
$ lq '.package.categories[]' -r Cargo.toml
command-line-utilities
parsing
convert jq output back into toml (-t
):
$ lq -t '.package.metadata' Cargo.toml
[binstall]
bin-dir = "lq-{ target }/{ bin }{ format }"
pkg-url = "{ repo }/releases/download/{ version }lq-{ target }{ archive-suffix }"
convert jq output to yaml (-y
) and set explicit toml input when using stdin (-T
):
$ lq -Ty '.dependencies.clap' < Cargo.toml
features:
- cargo
- derive
version: 4.4.2
jq style compact output:
$ lq '.profile' -c Cargo.toml
{"release":{"lto":true,"panic":"abort","strip":"symbols"}}
To shortcut passing input formats, you can add alias tq='lq --input=toml'
in your .bashrc
/ .zshrc
(etc).
Infers input format from extension, or set explicitly via -J
or --input=json
.
$ lq -Jy '.ingredients | keys' < test/guacamole.json
- avocado
- coriander
- cumin
- garlic
- lime
- onions
- pepper
- salt
- tomatoes
Using JSON input is kind of like talking to jq
directly, with the benefit that you can change output formats, or do inplace edits.
Default is going from yaml
input to jq
output to allow further pipes into jq
.
-J
json input, -T
toml input (shorthands for --input=FORMAT
)-y
yaml output, -t
toml output (shorthands for --output=FORMAT
)Ex;
lq
:: yaml -> jq outputlq -t
:: yaml -> tomllq -y
:: yaml -> yamllq -Tt
:: toml -> tomllq -Jy
:: json -> yamljq -Ty
:: toml -> yamljq -Jt
:: json -> tomlOutput formatting such as -y
for YAML or -t
for TOML will require the output from jq
to be parseable json.
If you pass on -r
,-c
or -c
for raw/compact output, then this output may not be parseable as json.
Two things you cannot do in jq
:
Split a bundle of yaml files into a yaml file per Kubernetes .metadata.name
key:
mkdir -p crds
curl -sSL https://github.com/prometheus-operator/prometheus-operator/releases/download/v0.82.1/stripped-down-crds.yaml \
| lq . -y --split '"crds/" + (.metadata.name) + ".yaml"'
Patch a json file (without multiple pipes):
lq -i '.SKIP_HOST_UPDATE=true' ~/.config/discord/settings.json
Any weird things you can do with jq
works. Some common (larger) examples:
Select on yaml multidoc:
$ lq '.[] | select(.kind == "Deployment") | .spec.template.spec.containers[0].ports[0].containerPort' test/deploy.yaml
8000
Escaping keys with slashes etc in them:
lq '.updates[] | select(.["package-ecosystem"] == "cargo") | .groups' .github/dependabot.yml
You can import jq modules e.g. k.jq:
$ lq 'include "k"; .[] | gvk' -r -L$PWD/test/modules < test/deploy.yaml
v1.ServiceAccount
rbac.authorization.k8s.io/v1.ClusterRole
rbac.authorization.k8s.io/v1.ClusterRoleBinding
v1.Service
apps/v1.Deployment
The project respects RUST_LOG
when set, and sends these diagnostic logs to stderr:
$ RUST_LOG=debug lq '.version' test/circle.yml
2023-09-18T23:17:04.533055Z DEBUG lq: args: Args { input: Yaml, output: Jq, yaml_output: false, toml_output: false, in_place: false, jq_query: ".version", file: Some("test/circle.yml"), compact_output: false, raw_output: false, join_output: false, modules: None }
2023-09-18T23:17:04.533531Z DEBUG lq: found 1 documents
2023-09-18T23:17:04.533563Z DEBUG lq: input decoded as json: {"definitions":{"filters":{"on_every_commit":{"tags":{"only":"/.*/"}},"on_tag":{"branches":{"ignore":"/.*/"},"tags":{"only":"/v[0-9]+(\\.[0-9]+)*/"}}},"steps":[{"step":{"command":"chmod a+w . && cargo build --release","name":"Build binary"}},{"step":{"command":"rustc --version; cargo --version; rustup --version","name":"Version information"}}]},"jobs":{"build":{"docker":[{"image":"clux/muslrust:stable"}],"environment":{"IMAGE_NAME":"lq"},"resource_class":"xlarge","steps":["checkout",{"run":{"command":"rustc --version; cargo --version; rustup --version","name":"Version information"}},{"run":{"command":"chmod a+w . && cargo build --release","name":"Build binary"}},{"run":"echo versions"}]},"release":{"docker":[{"image":"clux/muslrust:stable"}],"resource_class":"xlarge","steps":["checkout",{"run":{"command":"rustc --version; cargo --version; rustup --version","name":"Version information"}},{"run":{"command":"chmod a+w . && cargo build --release","name":"Build binary"}},{"upload":{"arch":"x86_64-unknown-linux-musl","binary_name":"${IMAGE_NAME}","source":"target/x86_64-unknown-linux-musl/release/${IMAGE_NAME}","version":"${CIRCLE_TAG}"}}]}},"version":2.1,"workflows":{"my_flow":{"jobs":[{"build":{"filters":{"tags":{"only":"/.*/"}}}},{"release":{"filters":{"branches":{"ignore":"/.*/"},"tags":{"only":"/v[0-9]+(\\.[0-9]+)*/"}}}}]},"version":2}}
2023-09-18T23:17:04.533650Z DEBUG lq: jq args: [".version"]
2023-09-18T23:17:04.538606Z DEBUG lq: jq stdout: 2.1
2.1
Because yaml is the default input language, you can use it as your top level yq
executable with a symlink or alias:
# globally make yq be lq
ln -s $(which lq) /usr/local/bin/yq
# alias yq to lq in shell environment only
alias yq=lq
It is mostly compatible with python-yq
(which uses jq
syntax) but differs from go yq (which invents its own syntax).
(This use-case was the first use-case for this tool, i.e. to get rid of heavy python deps in CI images)