Skip to content

Repository files navigation

YAML.sh — YAML in shell. No, really.

A serious YAML tool in one delightfully questionable medium.

Latest release POSIX shell plus AWK

Website · Docs · Recipes · YAML support


YAML.sh queries, transforms, validates, and edits YAML in one readable POSIX shell file with portable AWK inside. It can change exactly what you asked for without rewriting the comments and formatting around it.

$ ysh '.books[] | select(.read) | .title' reading.yml
Piranesi
The Left Hand of Darkness

$ ysh --preserve-only --diff '.theme = "midnight"' settings.yml
--- a/settings.yml
+++ b/settings.yml
@@ -1 +1 @@
-theme: light # terminal colours
+theme: midnight # terminal colours

No extra runtime or package manager. The constraint is the fun part.

Install

brew install azohra/tools/ysh

Or install the checksum-pinned release artifact:

curl -fsSL https://yaml.azohra.com/install | sh

Choose another directory with YSH_INSTALL_DIR="$HOME/.local/bin".

Read-only queries require /bin/sh and AWK. --check, --diff, and -i also use mktemp, cp, cmp, mv, rm, and wc from the host.

What makes it useful

Query and transform

Use paths, pipes, filters, reducers, construction, and updates without flattening away YAML types, anchors, aliases, or merge keys.

ysh '.albums | map(select(.rating >= 9)) | map(.title)' music.yml
ysh -n -o yaml '{name: "Ada", tags: [awk, yaml]}'
ysh -o yaml '.count += 1 | del(.draft)' notes.yml
ysh eval-all '. as $doc ireduce ({}; . * $doc)' defaults.yml local.yml

Edit YAML without eating the comments

ysh --check '.image.tag = "stable"' services/*.yml
ysh --diff '.image.tag = "stable"' services/*.yml
ysh --preserve-only -i '.image.tag = "stable"' services/*.yml

YAML.sh can update scalars, collections, block scalars, comments, and ordering while leaving unrelated text alone. --preserve-only refuses a change when it cannot keep that promise.

--check and --diff write nothing and return 0 when clean, 1 when files would change, and 2 on error. Multi-file writes are fully prepared before the first replacement, skip unchanged files, stop if a file changes after YAML.sh reads it, and roll back a failed write.

Validate, patch, and convert

ysh --schema service.schema.json '.' service.yml
ysh --apply-patch change.json --preserve-only --diff service.yml
ysh --merge-patch production.json -i service.yml
ysh --json --generate-patch desired.yml '.' current.yml > change.json

JSON Pointer, JSON Patch, Merge Patch, and a documented JSON Schema profile are built in. YAML.sh reads and writes JSON, YAML, TOML, INI, and XML; expression codecs cover properties, CSV, TSV, Base64, URI, and shell quoting.

Inspect strange YAML

ysh --type '.release.created' config.yml
ysh '[.services[0].port | line, .services[0].port | column]' config.yml
ysh --events config.yml
ysh --ast config.yml
ysh --explain=json --diff '.image.tag = "stable"' deploy.yml 2>changes.jsonl

Events and AST output show how YAML.sh understood a document. Explain mode reports selected paths, changes, and formatting decisions without logging values.

Trust model

YAML files are data; queries are programs. Queries cannot execute commands or open network connections, but they can explicitly read environment variables or local files, and eval can compile a dynamically supplied expression. Those capabilities can be disabled independently. Read security and limits before running untrusted input.

Know the boundary

YAML.sh documents what it supports:

Unsupported syntax fails clearly rather than returning a plausible result.

Build and contribute

make all

Development source is modular under src/awk/; the build assembles the single ysh artifact. Start with DESIGN.md, then read the internals and development guides.

License

MIT

About

A portable, yq-shaped YAML processor in one readable POSIX shell + AWK file.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages