jf(1)

πŸ“¦ version 1.0.0, in nixos 26.05, nixpkgs unstable

πŸ’… jf(1) β€” like, the JSON formatter of your dreams ✨

okay so bestie, welcome to jf, from the General Commands Manual β€” it's a template renderer that takes a template plus some values and spits out JSON (or YAML, we'll get there πŸ‘€). This page is literally gonna have you shipping valid JSON in like five minutes. no cap. 🫢


🌸 USAGE 🌸

jf [OPTION]... [--] TEMPLATE [VALUE]... [NAME=VALUE]... [NAME@FILE]...

That's the whole shape of it: options first, then a TEMPLATE, then your positional VALUEs, then NAME=VALUE pairs, then NAME@FILE pairs. Order matters, bestie β€” more on that in RULES πŸ’–


✨ OPTIONS ✨

  • - β€” this is just an alias for -f -, i.e. read the template from stdin 🧚
  • -- β€” stop parsing CLI options. periodt, everything after this is not an option πŸ’…
  • -r, --raw β€” print the raw rendered value without any formatting
  • -p, --pretty β€” pretty print the JSON formatted output (yes she's aesthetic ✨)
  • -y, --yaml β€” print the output as YAML instead of JSON 🌈
  • -h, --help β€” print this help message
  • -v, --version β€” print the version number
  • -f, --file β€” treat the template argument as a file to read from πŸ“

πŸ¦‹ TEMPLATE πŸ¦‹

So the template should render into valid YAML. That's the vibe check it has to pass. It can contain the following placeholders:

  • %% β€” a literal % character
  • %s, %q β€” read positional argument
  • %-s, %-q β€” read stdin
  • %(NAME)s, %(NAME)q β€” read named value from argument
  • %(NAME=DEFAULT)s, %(NAME=DEFAULT)q β€” placeholder with default value
  • %(NAME@FILE)s, %(NAME@FILE)q β€” read default value from file path
  • %(NAME@-)s, %(NAME@-)q β€” read default value from stdin
  • %(NAME?)s, %(NAME?)q β€” nullable placeholder that defaults to null
  • %(NAME)?s, %(NAME)?q β€” optional placeholder that defaults to blank
  • %*s, %*q β€” expand positional args as array items
  • %*-s, %*-q β€” expand stdin as array items
  • %**s, %**q β€” expand positional args as key value pairs
  • %**-s, %**-q β€” expand stdin as key value pairs
  • %(NAME)*s, %(NAME)*q β€” expand named args as array items
  • %(NAME)**s, %(NAME)**q β€” expand named args as key value pairs

And the golden rule, bestie: use placeholders with suffix q for safely quoted JSON string, and s for JSON values other than string. q = quoted = safe string πŸ’– s = everything else πŸ”₯


πŸ‘‘ RULES πŸ‘‘

  • Pass values for positional placeholders in the same order as in the template ⭐
  • Pass values for named placeholders using NAME=VALUE syntax
  • Pass values for named array items using NAME=ITEM_N syntax
  • Pass values for named key value pairs using NAME=KEY_N NAME=VALUE_N syntax
  • Pass values to stdin following the order and separate them with null byte ( ) 🫢
  • Use NAME@FILE syntax to read from file where FILE can be - for stdin
  • Do not pass positional values after named values πŸ™ˆ (she will not be happy)
  • To allow merging arrays and objects via expansion, trailing comma after s and q, if any, will be auto removed if no value is passed for the expandable placeholder ✨

πŸ’œ EXAMPLES πŸ’œ

okay these are iconic, let's go:

  • Run: jf %s 1
  • Out: 1
  • Run: jf %q 1
  • Out: "1"
  • Run: jf '{%**q}' one 1 two 2 three 3
  • Out: {"one":"1","two":"2","three":"3"}
  • Run: seq 1 3 | xargs printf '%s ' | jf '[%*-s]'
  • Out: [1,2,3]
  • Run:
jf "{%q: %(value=default)q, %(bar)**q}" foo value=bar bar=biz bar=baz
  • Out: {"foo":"bar","biz":"baz"}
  • Run:
jf "{str or bool: %(str)?q %(bool)?s, nullable: %(nullable?)q}" str=true
  • Out: {"str or bool":"true","nullable":null}
  • Run:
jf '{1: %s, two: %q, 3: %(3)s, four: %(four=4)q, "%%": %(pct?)q}' 1 2 3=3
  • Out: {"1":1,"two":"2","3":3,"four":"4","%":null}

πŸŽ€ SHELL ALIASES πŸŽ€

You can set the following aliases in your shell, and honestly? you should. main character energy:

  • alias str='jf %q'
  • alias arr='jf "[%*s]"'
  • alias obj='jf "{%**s}"'

Then you can use them like this πŸ’…

  • Run: str 1
  • Out: "1"
  • Run: arr 1 2 3
  • Out: [1,2,3]
  • Run: obj one 1 two 2 three 3
  • Out: {"one":1,"two":2,"three":3}

and then the flex 🧚:

  • Run:
obj 1 2 3 "$(arr 4 "$(str 5)")"
  • Out: {"1":2,"3":[4,"5"]}

and that's the whole page, bestie β€” you ate that πŸ’…βœ¨

sign-off szn: this was jf(1) from the General Commands Manual (that's the source + version tag, no date given on this one, she's mysterious like that πŸ¦‹). mwah, go render something gorgeous πŸ’–πŸŽ€

πŸ“¦ where this page comes from