Skip to content
shellmap

Show disk usage by folder

See which subdirectories consume the most disk space — for "where did 50GB go" investigations or post-clean audits.

How to show disk usage by folder in each shell

Bashunix
du -sh */ | sort -h

`-s` summarizes (one line per folder, not recursive listing of every file). `-h` is human-readable (`12K`, `45M`, `1.2G`). `sort -h` sorts the human-readable column properly (GNU sort 7.0+). `du -sh */ | sort -hr | head -10` for the top 10 largest. macOS BSD `du` lacks `-h` until macOS 10.12 (it has now); on really old BSDs use `du -sk */ | sort -n` (kilobytes + numeric sort).

Zshunix
du -sh */ | sort -h

Same external. For a much more visual tree view, install `ncdu` (`brew install ncdu` / `apt install ncdu`) — interactive terminal UI that drills into folders, shows percentages, and lets you delete from inside the UI. `ncdu /path` is the one-liner. `dust` (Rust rewrite) is similar with a nicer default colour scheme.

Fishunix
du -sh */ | sort -h

Same external. Fish-specific quality-of-life: `du -sh */ | sort -h | tail -10` for the 10 biggest (since `sort -h` is ascending). For a top-N including hidden directories: `du -sh .[^.]* */ | sort -h`. The `.[^.]*` glob matches hidden dirs starting with `.` but excludes `.` and `..`.

PowerShellwindows
Get-ChildItem -Directory | ForEach-Object { [PSCustomObject]@{ Name = $_.Name; SizeMB = [Math]::Round((Get-ChildItem $_ -Recurse -File -ErrorAction SilentlyContinue | Measure-Object Length -Sum).Sum / 1MB, 2) } } | Sort-Object SizeMB -Descending

Recursively walks each top-level directory and sums file sizes. `-ErrorAction SilentlyContinue` swallows "access denied" errors that arise from system folders. `[Math]::Round(..., 2)` keeps two decimal places. For GB: `... / 1GB`. For very large trees, this is SLOW because it walks every file — for repeat audits, use `Robocopy /L /MIR /BYTES /NJH /NJS dir empty | findstr /R "Bytes"` to get folder size in one pass.

cmd.exewindows
for /d %d in (*) do @(robocopy "%d" \\nul /L /S /BYTES /NJH /NJS /NFL /NDL | findstr /R "Bytes :")

cmd has NO native `du`. The `robocopy /L /BYTES` trick uses the COPY-DRY-RUN report to extract total bytes — `/L` is list-only, `/BYTES` reports bytes, `/NJH /NJS /NFL /NDL` suppress headers/file-lists. Realistically: shell out to pwsh: `powershell -NoProfile -Command "Get-ChildItem -Directory | ForEach-Object { @{ Name = $_.Name; Size = (Get-ChildItem $_ -Recurse | Measure-Object Length -Sum).Sum } }"`. Or install `du` from GnuWin32 / scoop (`scoop install gnu-coreutils`).

Equivalents listed for Bash, Zsh, Fish, PowerShell, cmd.exe.

Gotchas & notes

  • `du` reports DISK USAGE (how many disk blocks the file occupies, INCLUDING filesystem block alignment overhead). `ls -l` and pwsh `Length` report LOGICAL SIZE (the file's byte count). For files smaller than the filesystem block size (typically 4KB), `du` rounds UP — a 100-byte file consumes 4KB on disk. On directories full of tiny files, the numbers can diverge by 10×+.
  • `du` follows symlinks differently across BSD and GNU. GNU `du -L` follows; `du` alone does NOT. macOS BSD `du -L` ALSO follows; bare `du` does NOT. For "size as you see it in Finder / Explorer" (resolving symlinks): always pass `-L`. For "actual on-disk consumption" (one file per inode): bare `du`.
  • pwsh `Get-ChildItem -Recurse | Measure-Object Length -Sum` reports LOGICAL size (`Length` is bytes from the metadata). To get DISK USAGE (cluster-aligned), use `Get-CimInstance -ClassName Win32_LogicalDisk -Filter "DeviceID='C:'"` for the volume-level free/used view, or `fsutil file queryallocation file.bin` for per-file disk allocation.
  • On Linux ext4 / XFS with reflink-supporting filesystems (btrfs, ZFS, modern XFS), copy-on-write copies share blocks. A `cp --reflink` of a 10GB file appears as 10GB in `ls -l` but consumes ~0 blocks in `du` until one of the copies is modified. `du --apparent-size` reports the logical size for these cases (similar to `ls -l` aggregate).

Related commands

Related tasks