Neat; seems about every quarter or so one of these types of tools is highlighted here.
Awaiting all the responses from people to show off or list what tool they've landed on to support their specific use cases; I always learn a lot from these.
Personally I think this is a problem better spent by fixing the shell. There’s a few alt shells out there now, Nushell, Elvish plus the one I help maintain, Murex (https://murex.rocks).
I’m obviously going to biased here, but it’s definitely worth your time checking out some alt shells.
I did not know about Murex. This actually looks pretty cool! Or at least a definite improvement. How is it regarding using it as a scripting language in lieu of Bash?
The last shell I was intrigued by was es-shell which despite being old is still being updated and uses functional semantics while still looking like a shell language. I had chatgpt generate a comparison of all these with Bash (take with a grain of salt, I already had to correct at least one thing):
I'm a bit confused as to the use case. Is it just a way to interact with json/yaml style documents as if they were a structured database, but from the command line? Kind of an in-between for those moments you don't want to write a quick script to batch modify files?
It looks really well done, I think I'm just failing to see how this is more beneficial than just opening a single file in the editor and making changes, or writing a quick functional script so you have the history of the changes that were made to a batch of files.
If someone could explain how I could (and why I should) add a new tool to my digital toolbelt, I'd greatly appreciate it.
I use jq for this kind of thing several times a week. It’s great for piped data - things like running curl to fetch JSON, then piping it though to reformat it in different ways.
Here’s a jq expression I used recently to turn a complete GitHub Issues thread into a single Markdown document:
curl -s "https://api.github.com/repos/simonw/shot-scraper/issues/1/comments" \
| jq -r '.[] | "## Comment by \(.user.login) on \(.created_at)\n\n\(.body)\n"'
I use this pattern a lot. Data often comes in slightly the wrong shape - being able to fix that with a one-liner terminal command is really useful.
PowerShell[0]'s built-in Microsoft.PowerShell.Utility[1] module has commands to `Convert-From...` or `Convert-To...` JSON, CSV, a version of XML (CliXML), or custom key/value pairs (StringData) into objects, which can then be manipulated. Combined with IO cmdlets from the built-in module Microsoft.PowerShell.Management[2] such as `Get-Content` and `Set-Content`, a fair chunk of flat-file storage should be able to be made mutable with PowerShell.
Weirdly enough, INI is not that well-supported; but yeah, it's loads better than stuff like curl/jq for the very common JSON, YAML and other structured data cases (which includes near-100% native support for what you are commonly running shell utilities for: ls, ps, and so forth). The best part is that it's integrated into the shell language at the top-level so you can leverage whatever you learn to sort, filter and process all kinds of structured data, and explore and manipulate in a straightforward way. It's very powerful to freely intermix gci, gi, irm output and script together these various sources.
And it's full of delightful tricks, like when you discover properly-throttled parallelism is easy (% -parallel {}) and you don't need to dive into yet another tool-specific abstruse sublanguage.
I used yq last week to scan through all the Java projects (i.e. Maven pom.xml-files) within our org to check which ones inherit from the corporate pom.
For things that are mostly shell scripts and things in a similar family (Ansible playbooks, deployment pipelines etc.) and where you need to modify a structured file quickly, it's usually much faster to use the DSL provided by the tool than calling out to various scripts to extract or modify a single JSON key.
People often say that they'd prefer to write their shell scripts in Python or even Go these days, but the problem there is that the elements of structured programming makes the overall steps difficult to follow. Typically, the paradigm with use cases adjacent with shell scripts is to be able to view what it is doing without any sort of abstractions.
Having done similar things to this in the past, I rebut: no it wouldn't. :)
It's not trivial to change a particular
version: 2.33
line in a JSON file, when it's possible that string is present in many places with different meanings.
You can just wing it and be right 90% of the time; but that thoughtlessness will bite you in time.
Multiply that by the number of different context you might want to make "the same" change in a project, and sed/awk get to be a poor fit. YAML and JSON are just plain not line oriented.
You really need something with a featureset like xpath to set the semantically correct node to the right value, and every few years the kids decide they need YET ANOTHER thing that's not XML, or Yaml, or JSON, or TOML, or..
Maybe I am too prescriptive of your setup, but I don't really see "version: 2.33" making sense. Why not something akin to "version: __BUILD_NUMBER__" being actually checked into your tree, and then your build pipeline filling it in at build time?
Keeping a copy of the build number checked into your source tree seems like asking for trouble when the build number is so intrinsically tied to a single build pipeline run.
the in-between mode that you mention but seem to dismiss it is the way most traditional unixheads work with data most of the time: from the command line
editor? when i pull up emacs, 50% of the time it's write emacs macros, and I do that because shell scripts don't easily go backward in the stream. (something rarely mentioned about teco was that it was a stream editor that would chew its way forward through files; you didn't need the memory to keep it all in core, and it could go backward within understandable limits)
writing an actual shellscript is only for when it's really hairy, you are going to be repeating it and/or you need the types of error handling that cloud up the clarity of the commandline
the commandline does provide rudimentary "records" in the saved history
one benefit (idk if it applies here) is if the select/put/delete statements didn’t require loading the data in memory; so you could query massive data files with limited RAM and not have to solve that problem yourself for each data storage format you’re working with
Awaiting all the responses from people to show off or list what tool they've landed on to support their specific use cases; I always learn a lot from these.