tuniq is a Unix command-line utility for streaming frequency analysis.
- Replaces
sort | uniq -c | sort -rn | headwith one tool. - Works on unsorted stdin or multiple files.
- Uses worker sharding for multicore throughput.
- Sorts only unique values for deterministic output.
- Writes results to stdout and diagnostics/stats/progress to stderr.
go install github.com/flaviomartins/tuniq/cmd/tuniq@latestBuilding from source requires Go 1.25 or newer.
Download binaries from GitHub Releases and place tuniq in your PATH.
Release binaries are built with the latest stable Go toolchain.
make buildor:
go build -o tuniq ./cmd/tuniqtuniq [flags] [file ...]If no files are provided, tuniq reads from stdin. Multiple files are processed as one logical stream.
Flags:
-n Ntop N entries-l N,--max-lines Nstop after reading N lines (0 means no limit)-ashow all entries-rreverse ordering (ascending count)-cshow counts (default true)--no-counthide counts-u N,--update-every Nlive updates every N lines (plain output only)--no-statushide the live status bar (spinner, rate, sparkline)--statusshow the live status bar (overridesstatus=falsein config)--csvCSV output--jsonJSON output--workers Nworker shards (default:GOMAXPROCS)--progress,--progress-every,--progress-every-secondsprogress cadence--stats,--stats-rssprocessing stats--memory-limit-byteshard stop on estimated counter memory--version,--help
tuniq -n 10 data.txttuniq data.0.txt data.1.txt data.2.txtcurl -q -sN https://stream.wikimedia.org/v2/stream/recentchange \
| jq --unbuffered -r '.title // empty' \
| tuniq -n 20 -u 1From a stream with ssecat
ssecat https://stream.wikimedia.org/v2/stream/recentchange \
| jq --unbuffered -r '.title // empty' \
| tuniq -n 20 -u 1cat queries.txt | tuniq --no-countcat queries.txt | tuniq --csv -n 100
cat queries.txt | tuniq --json -n 100tuniq loads defaults from these paths in order (later entries override earlier):
~/.tuniqrc(legacy homedir)~/.config/tuniq/.tuniq(or OS equivalent fromos.UserConfigDir)./.tuniqrc(project override)
Config format is key=value with # comments. CLI flags always override config values.
Supported keys:
top_n=20
max_lines=0
show_all=false
reverse=false
show_count=true
update_every=0
output=plain
workers=8
progress=true
progress_every=500000
progress_every_seconds=0
stats=false
stats_rss=false
status=true
memory_limit_bytes=0Config: ~/.config/tuniq/.tuniq
State: ~/.local/state/tuniq (or OS equivalent)
cmd/tuniq: CLI entrypoint and signal wiring.pkg/processor: stream processing orchestration and runtime pipeline.pkg/platform: OS-specific RSS helpers.pkg/config,pkg/output,pkg/version: configuration, output formatting, and build metadata.
Default plain output:
15234 apple
11201 orange
9321 banana
Ordering is deterministic:
- count descending (or ascending with
-r) - value alphabetical as tiebreak
When live updates are enabled (-u), a status bar appears below the top-N table:
15234 apple
11201 orange
9321 banana
8102 grape
7654 mango
⠹ streaming 1,250,000 lines ▁▂▄▅▇▇█▆ 45.2k/s
The top-N table redraws on the configured live cadences (-u for lines and
--progress-every-seconds for time). Between those redraws, tuniq still
refreshes the status bar about once per second so active streams do not look
stalled and idle open streams, including before the first line arrives, can
flip to waiting:
| Element | Meaning |
|---|---|
⠹ (spinning) |
Data is actively arriving — spinner advances with each update |
⠹ (frozen) |
Stream is open but silent — no EOF received yet |
streaming |
Lines are flowing in (green) |
waiting |
No new lines since last render (yellow) |
✓ complete |
EOF received — final counts are exact (dim) |
1,250,000 lines |
Total lines processed so far |
▁▂▄▅▇▇█▆ |
8-sample rolling throughput sparkline |
45.2k/s |
Current ingest rate |
Use --no-status (or status=false in config) to hide the bar entirely.
- Counting is shard-local, then merged.
- Sorting happens over unique keys, not total lines.
- Memory growth is proportional to cardinality.
--memory-limit-bytesaborts when estimate exceeds limit (spill-to-disk is not implemented).
make fmt
make vet
go test ./...
make buildContributions are welcome. Please run formatting, vet, and tests before opening pull requests.
MIT (see LICENSE).