Skip to content

Instantly share code, notes, and snippets.

@Freaky
Created November 12, 2025 12:13
Show Gist options
  • Select an option

  • Save Freaky/48d88a0b037f50bef62e9e09649d29fe to your computer and use it in GitHub Desktop.

Select an option

Save Freaky/48d88a0b037f50bef62e9e09649d29fe to your computer and use it in GitHub Desktop.
List ZFS datasets by used space and sum totals by volume
#!/bin/sh
zfs_usedsnap() {
local name_width
name_width=$(zfs list -H -o name | wc -L)
local size_width=8
zfs list -H -p -o name,usedsnap -s usedsnap | \
awk -v name_width="$name_width" -v size_width="$size_width" '
BEGIN {
printf "%-*s %*s\n", name_width, "NAME", size_width, "USEDSNAP"
}
{
if ($2 > 0) {
print_line($1, $2)
split($1, parts, "/")
pool = parts[1]
total[pool] += $2
}
}
END {
print ""
printf "%-*s %*s\n", name_width, "POOL", size_width, "USEDSNAP"
for (p in total) {
if (total[p] > 0) {
print_line(p, total[p])
}
}
}
function print_line(name, bytes) {
printf "%-*s %*s\n", name_width, name, size_width, zfs_nicebytes(bytes)
}
# ZFS-style humanisation: divide while over the multiplier, then try 2, 1, 0 decimal places
# Always returns a string of 5 characters or less
# Ref: zfs_nicenum_format in lib/libzutil/zutil_nicenum.c
function zfs_nicebytes(bytes, units, u, val, dp, out) {
split("B K M G T P E", units)
val = bytes
u = 1
while (val >= 1024 && u <= length(units)) {
val /= 1024
u++
}
if (u == 1 || bytes % (1024 ** (u - 1)) == 0) {
# If this is an even multiple of the base, always display without any decimal precision.
return sprintf("%d%s", val, units[u])
}
for (dp = 2; dp >= 0; dp--) {
out = sprintf("%.*f%s", dp, bytes / (1024 ** (u - 1)), units[u])
if (length(out) <= 5) return out
}
}
'
}
zfs_usedsnap
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment