Skip to main content

sumall

License: Apache 2.0

A fast, zero-dependency CLI that sums a column of numbers and reports the total in MB / KB / bytes.

Built for the everyday "add up these sizes" moment: paste from a spreadsheet, pipe du -sh output, or pass numbers as arguments. The per-line breakdown shows exactly which values were included, so the total is verifiable at a glance.

Features

  • Three input sources, first match wins: command-line arguments, piped stdin, the system clipboard (bare invocation)
  • du / ls -lh style suffixes: 768K, 1.9M, 2G, 15Gi — mixed units are normalized to bytes before summing
  • ls -l long-format lines: the size field is parsed as bytes (ls -lh suffixes honored); directory lines are skipped since their "size" is just the inode
  • Table pastes: markdown tables and spreadsheet TSV (Excel / Feishu clipboard) — the number can sit in any column; when a row holds several numbers, unit-marked cells win, then the last column (--column N pins one)
  • Trailing labels tolerated: 177K background.png parses as 177 KB; the label rides along in the breakdown
  • Unit-aware totals: bare numbers sum unitless; values with a K/M/G suffix are normalized to bytes first; --unit anchors bare numbers to a size unit
  • Per-line breakdown plus totals in MB / KB / bytes
  • Pure Python 3.10+ stdlib — no runtime dependencies, starts in ~60 ms

[!NOTE] Units follow the binary (MiB) convention — 1 MB = 1024 KB = 1,048,576 bytes — matching du -h / df -h output.

Usage

From arguments

Arguments are strict: every token must be a number (optionally with a suffix). A typo fails loudly instead of being silently skipped. Tokens may contain spaces or newlines, so pasting a whole column as one quoted argument works too.

$ ./main.py 10 37 6 1.46
source: arguments
input: 4 values

breakdown:
   1) 10     2) 37     3) 6      4) 1.46

total:
  54.46

Bare numbers stay unitless (the --unit flag anchors them); values with a K/M/G suffix are always normalized to bytes.

From the clipboard

Copy the numbers, then run bare — no arguments needed. Linux (X11 via xclip/xsel, Wayland via wl-paste) and macOS (pbpaste) are supported; the first tool found wins.

Clipboard (and stdin) parsing is line-based and lenient: each line is split into cells (tabs, then markdown pipes, then whitespace) and the value is located among them; lines with no number — headers, separators, prose, directories, summary rows — are skipped and counted in the header.

From stdin

$ du -sh img/* | ./main.py
source: stdin
input: 4 values, unit mixed

breakdown:
  13M app.bin       =  13.0000 MB
  1.9M audio.bin    =  1.9000 MB
  768K ota.bin      =  0.7500 MB
  1.7M sensor.bin   =  1.7000 MB

total:
  17.35 MB
  17766.40 KB
  18192794 bytes

From an ls -l paste

ls -l puts the size in field 5, not at the start of the line — a paste is recognized as long-format lines and the size field is taken as bytes (ls -lh suffixes like 12K are honored). Directory lines and the total summary are skipped:

$ ls -l | ./main.py
source: stdin
input: 4 values, unit mixed (3 lines skipped)

breakdown:
  11358B LICENSE        =  0.0108 MB
  499B main.py*         =  0.0005 MB
  1666B pyproject.toml  =  0.0016 MB
  3588B README.md       =  0.0034 MB

total:
  0.02 MB
  16.71 KB
  17111 bytes

From a table paste

Markdown tables and spreadsheet clipboard (Excel / Feishu copy = TSV) put the number after the name, in any column — both work. When a row holds several numbers (size and used, or a df -h row), cells carrying a unit marker win over bare ones, and otherwise the last column is taken; a yellow note is printed whenever that heuristic fired, so a wrong pick is visible:

$ ./main.py -c 2 < partitions.md
source: stdin
input: 3 values, unit mixed (2 lines skipped)

breakdown:
  13M app.bin      =  13.0000 MB
  1.9M audio.bin   =  1.9000 MB
  768K ota.bin     =  0.7500 MB

total:
  15.65 MB
  16025.60 KB
  16410214 bytes

-c N takes the Nth table column (counting all columns, not just numeric ones) instead of the heuristic; footer rows starting with total / 总计 / 合计 are always skipped so totals never count twice.

Units

Input line Parsed as
10 a bare number: summed as-is (no unit) when every value is bare; anchored to a unit when a suffix-marked value or --unit is present
768K / 768k 768 KB — suffix always wins over the default unit
1.9M / 15Gi / 1,048,576 1.9 MB / 15 GB / 1048576 of the default unit
2G 2 GB
177K file.png 177 KB, label file.png
| app.bin | 13M | 13 MB, label app.bin (markdown row)
ap<TAB>13.5 MB 13.5 MB, label ap (spreadsheet cell)
ap 13.5 16 several numbers: unit-marked wins, else last; -c N pins one
-rw-r--r-- 1 mi mi 11358 Sep 1 09:48 LICENSE 11358 bytes, label LICENSE
drwxr-xr-x 3 mi mi 4096 Sep 1 09:50 src/ skipped — directory inode size, not content
total 32 / 合计 17111 skipped — block counts and footer totals
30% 30 percent — percent-only input sums as-is, shown as xx.xx %
v1.2 / 2025-09-01 skipped — not sizes
hello skipped (stdin/clipboard) or an error (argument)

Use --unit B|KB|MB|GB to give bare numbers a size unit, e.g. ./main.py --unit KB 768 128 sums to 896 KB; without it, an all-bare input sums unitless (e.g. 46.4%-style or plain-count pastes).

Installation

No install is needed — run straight from a checkout:

$ ./main.py 10 37 1.46

Or install it as a sumall command on your PATH:

$ pip install -e .
$ sumall 10 37 1.46

Development

$ pip install -e ".[dev]"   # pytest + ruff
$ pytest                    # runs against src/ via pythonpath — no build step
$ ruff check src tests main.py
$ ruff format --check src tests main.py

CI (.github/workflows/ci.yml) lints and tests across Python 3.10–3.12 and additionally builds the wheel, installs it clean, and reruns the suite against the installed package.

License

This project is licensed under the Apache License, Version 2.0. See LICENSE or https://www.apache.org/licenses/LICENSE-2.0 for the full text.

Release files for sumall 0.0.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for sumall 0.0.2
File Size Uploaded
sumall-0.0.2.tar.gz 19.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for sumall 0.0.2
File Interpreter ABI Platform
sumall-0.0.2-py3-none-any.whl Python 3 none any Details

Total release size: 35.3 kB

Release files / sumall-0.0.2.tar.gz

Download URL sumall-0.0.2.tar.gz
Size 19.2 kB
Tags Source
SHA-256 checksum
How to use checksums
9a6ca800e1cf19c832e988513f2c349fdf9d21e1c9a2bae9c31f8f91c4f3b6ec
BLAKE2b-256 checksum
How to use checksums
f769be12d448fe5163e1ebce5dc02ff1bd903adfa8f9acbee0b63dc3392d0cc4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.10.12

Release files / sumall-0.0.2-py3-none-any.whl

Download URL sumall-0.0.2-py3-none-any.whl
Size 16.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
7bf2c194c876e040d61d537d22c3777730664a2a356a402e5225f57a21303324
BLAKE2b-256 checksum
How to use checksums
663f3c1fb564aec76f3cb7d4dfe25227b19ddc9246465c1a88ccefcab243c5df
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.10.12

Release history Release notifications | RSS feed

This release

0.0.2 This release

2 release files

0.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page