Dedupe a JSON file in place, safely
jq can't write to the file it just read — sponge (from moreutils) buffers the whole pipeline in memory before opening the destination, so any in-place edit (dedupe, reformat, prune) collapses to one line instead of a temp-file-and-mv dance.
Setup
- → apt install moreutils # provides sponge, ts, pee alongside it
Cost per run
free
The one-liner
$ jq 'sort_by(.host) | unique_by(.host)' hosts.json | sponge hosts.jsonWhat each stage does
- [01] bash
echo '[{"host":"api.example.com","status":"up"},{"host":"db.example.com","status…Stand-in for any local JSON state that accumulates duplicates over time — a host inventory, a dedupe cache, a queue snapshot. 5 rows, 2 hosts repeated. - [02] jq
jq 'sort_by(.host) | unique_by(.host)' hosts.jsonRead hosts.json, sort by host, then keep only the first row per host. Output goes to stdout — hosts.json itself is still untouched at this point. - [03] sponge
sponge hosts.jsonSoaks up all of stdin into memory before it opens hosts.json for writing. `jq ... hosts.json > hosts.json` would truncate the file to empty the instant the shell's redirection opens it — sponge removes that race entirely. - [04] cat
cat hosts.jsonConfirms the rewrite landed: 5 rows in, 3 unique rows out, same path, no temp file left behind.
Expected output (sample)
[
{
"host": "api.example.com",
"status": "up"
},
{
"host": "cache.example.com",
"status": "up"
},
{
"host": "db.example.com",
"status": "down"
}
]Caveats & tips
- Verified on moreutils 0.69 (Ubuntu 24.04 apt package); sponge takes no --version flag, that's normal.
- sponge buffers entirely in memory — great for KB/MB config, cache, and state files; not the tool for multi-GB pipelines.
- If the upstream command crashes, sponge writes nothing at all — the file is never left half-truncated, which is the whole point.
- The general shape is `<command> file | sponge file` any time you'd otherwise reach for `cmd file > tmp && mv tmp file` — works with sed, yq, csvsort, anything that reads a file and prints a new version of it.