bashumerate — A programmable iterator for your shell

Ever found yourself writing this?

for f in *.txt; do
  wc -l "$f"
done

Or this?

find . -name '*.sh' -exec wc -l {} +

Or maybe you pipe into xargs and pray your filenames don’t have spaces:

find . -name '*.log' | xargs rm

These all work, but each has its own syntax, its own flags, its own quirks. I wanted something simpler — one consistent way to iterate over anything.

Enter bashumerate

enumerate -f '*.sh' -- 'wc -l {}'

That’s it. -f for files, {} is the placeholder for each item, -- separates source from command.

It supports four source types:

Flag Source Example
-f Files enumerate -f '*.sh' -- wc -l {}
-l Lines enumerate -l /etc/hosts -- 'echo {}'
-r Range enumerate -r 1 10 -- 'printf "n=%d\n" {}'
-L List enumerate -L a b c -- 'echo item: {}'

If you omit the command, items are printed to stdout — pipe them anywhere:

enumerate -f '*.log' | xargs rm
cat urls.txt | enumerate -l - | while read url; do curl -s "$url"; done

Why not just use a for loop?

You can. But enumerate gives you:

  • Consistent syntax — same {} placeholder for files, lines, ranges, or lists
  • Template mode — single-quoted commands work as shell templates: enumerate -f '*' -- 'cat {} | head -5'
  • Filters--include and --exclude with glob patterns
  • NUL-safe-0 flag for NUL-delimited output
  • Extensible — drop a file in lib/enumerators/ to add custom sources

Adding your own source

Create lib/enumerators/docker.sh:

enumerate_source_docker() {
  docker ps --format '' | while read -r name; do
    printf '%s\0' "$name"
  done
}

Now you can do:

enumerate docker -- 'docker restart {}'

That’s it. No registration, no config — just name the function enumerate_source_<name> and it’s available.

Under the hood

The core is about 140 lines of bash. Sources are NUL-delimited internally (safe for spaces and special chars), and the {} placeholder is replaced at the shell level — no sed, no eval tricks.

enumerate -f '*.md' -- 'wc -l {}'
# → wc -l README.md
# → wc -l docs/guide.md

Install

basher install wallach-game/bashumerate

# or just clone and symlink
git clone https://github.com/wallach-game/bashumerate.git
ln -s "$PWD/bashumerate/bin/enumerate" ~/.local/bin/

The name

“bash” + “enumerate” — a bash enumerator. Not creative, but it does what it says.

Check it out: github.com/wallach-game/bashumerate