group-object — Bucket items by a property — sort | uniq -c equivalent across all 5 shells
Equivalents in every shell
sort file.txt | uniq -cThe canonical Unix idiom: `sort` first (`uniq` only deduplicates ADJACENT lines), then `uniq -c` prefixes each with its count. Add `| sort -nr` for count-descending order. For grouping by a field, pre-process with `awk` or `cut`.
sort file.txt | uniq -cSame pipeline as bash. For multi-field aggregation, the portable awk idiom is `awk '{ c[$1]++ } END { for (k in c) print c[k], k }'`.
sort file.txt | uniq -cSame pipeline. Fish has no native grouping primitive; the awk idiom above works unchanged.
Get-Content file.txt | Group-ObjectAliased as `group`. Returns `GroupInfo` objects with `.Count`, `.Name` (the property value), and `.Group` (the array of items in the bucket). `-Property <name>` groups by that property; `-NoElement` omits `.Group` for count-only output; `-AsHashTable` returns a Hashtable keyed by the property — perfect for lookups.
sort file.txt | find /c /v ""cmd has NO native count-by-value. The `find /c /v ""` trick counts ALL non-empty lines but not per-value. For real grouping, shell out: `powershell -Command "Get-Content file.txt | Group-Object | Select Count,Name"`.
Worked examples
Count occurrences of each line and sort by frequency
sort access.log | uniq -c | sort -nrGet-Content access.log | Group-Object | Sort-Object Count -DescendingGroup running processes by name; show top 5 by total memory
Get-Process | Group-Object Name | Sort-Object @{e={($_.Group|Measure-Object WS -Sum).Sum}} -Descending | Select-Object -First 5Build a hashtable lookup of CSV rows by department
Import-Csv users.csv | Group-Object Department -AsHashTable -AsStringGotchas
- `Group-Object` MATERIALISES every input into memory — it cannot stream. On multi-GB inputs this blows the heap. The Unix `sort | uniq -c` pipeline DOES stream (sort spills to disk via `$TMPDIR`), so for huge files it remains the faster and more reliable choice even from pwsh: `Get-Content -Raw huge.txt | & sort | & uniq -c` (on a pwsh host with the GNU tools on PATH).
- `-AsHashTable` requires `-AsString` when the property values aren't inherently strings — otherwise the resulting Hashtable keys are objects you can't look up by string. `Group-Object Department -AsHashTable -AsString` is the safe idiom for `Import-Csv` results.
- `-Property` accepts a script block for computed groupings: `Get-ChildItem | Group-Object { $_.LastWriteTime.Year }` buckets files by year. Multiple properties group by the COMPOSITE: `Group-Object Department,Title` returns one bucket per `(Department, Title)` pair, with `.Name` rendered as `'Engineering, Senior'`.
- Without `-NoElement`, the `.Group` property holds the FULL array of grouped objects — fine for small inputs, but a memory hog when grouping millions of items just to get counts. Pass `-NoElement` for count-only output; the working set is ~10× smaller on large inputs.
- Case sensitivity: `Group-Object` is CASE-INSENSITIVE by default for string keys (`'Red'` and `'red'` go into the same bucket). Pass `-CaseSensitive` to split them. The Unix `sort | uniq -c` pipeline is case-sensitive by default — set `LC_ALL=C` if you also need byte-exact comparison (no Unicode normalisation).