Skip to content

excelano/xshape

Repository files navigation

xshape — reshape for tabular data

xshape changes the geometry of a single table — which axis holds which cells — and never changes, filters, or aggregates a value. Pivot a long key/value table into a matrix, unpivot a wide export back to long so it can be queried, split one column into several, explode a delimited cell into rows, merge several columns into one, or transpose a table that arrived sideways. Every cell that goes in comes out somewhere else, unchanged.

Project page: https://excelano.com/xshape/

$ xshape unpivot --cols '[fy2020]:[fy2026]' --into fiscal_year,spend contracts.csv

contract_id,vendor,fiscal_year,spend
0000000000000000000002256,IDEMIA Identity & Security USA LLC,fy2020,0.00
0000000000000000000002256,IDEMIA Identity & Security USA LLC,fy2021,0.00
0000000000000000000002256,IDEMIA Identity & Security USA LLC,fy2022,0.00
...

$ xshape explode --col '[application_names]' --sep '; ' contracts.csv
# one row per application, every other field repeated — 9,217 pieces → 9,217 rows

Why

Every messy-CSV workflow eventually hits the same wall: the data is correct but oriented wrong for the next step. A wide fiscal-year export has to go long before SQL can group it. A long event log has to spread into a matrix before a human can read it. A cell holds three application names glued by a semicolon and each needs its own row. The sheet arrived transposed. None of this changes what the data says — it only changes which axis holds what.

Until now that job had no home in a focused tool, so the reach was always for a general reshaper with a hundred other features attached — Miller, tidyr, a pandas melt/pivot/explode script. xshape is that one job, done with a bright boundary: it moves cells between the row and column axes, requires you to state your separator (it never guesses one), and errors rather than aggregate when two cells would collide — because the moment a reshape needs a SUM, it has become a query.

The family

xshape is the reshaping verb in a family of small tools for messy tabular data, split by what changes:

  • xray observes — profiles the file, reports hazards, changes nothing.
  • xled edits cell values in place (sed and awk for tables).
  • xshape changes the shape of the grid, and never touches the values.
  • xql queries the row set — filter, aggregate, group, join.

The line that keeps xshape focused: it moves cells between axes and refuses to aggregate. An aggregating pivot (pivot … SUM) is a query — that belongs to xql or DuckDB. xshape shares xled's column-addressing dialect (letters, [bracketed names], ranges), so the family reads as one language with different verbs.

Install

Debian and Ubuntu

Add the Excelano apt repository once:

curl -fsSL https://excelano.com/apt/setup.sh | sudo sh

Then:

sudo apt install xshape

Both amd64 and arm64 packages ship with every release.

Homebrew

brew install excelano/tap/xshape

crates.io

cargo install xshape

Curl (any Linux or macOS)

curl --proto '=https' --tlsv1.2 -LsSf https://raw.githubusercontent.com/excelano/xshape/main/install.sh | sh

To remove it: swap install.sh for uninstall.sh in that line.

Usage

xshape <verb> [options] file.csv     # reshape; result to stdout| xshape <verb> [options]          # reshape piped stdin
xshape <verb> -i [options] file.csv  # write the result back to the file (like sed -i)

The reshaped table goes to stdout by default — the whole new grid in view before you commit. -i/--in-place[=.bak] writes it back.

Verb Direction Example
unpivot wide → long xshape unpivot --cols '[q1]:[q4]' --into quarter,value f.csv
pivot long → wide xshape pivot --names-from '[metric]' --values-from '[value]' f.csv
split one col → several xshape split --col '[name]' --sep ', ' --into last,first f.csv
explode cell → rows xshape explode --col '[tags]' --sep '; ' f.csv
merge several → one xshape merge --cols '[first],[last]' --sep ' ' --into name f.csv
transpose swap axes xshape transpose f.csv

Columns are addressed like xled: a letter (C, AF), a bracketed header name ([first name]), and — for the set-taking verbs — ranges (E:K) and comma lists ([id],D:E). split/explode/merge require an explicit --sep and split on it literally (spaces included); nothing is ever trimmed, dropped, or aggregated. pivot errors on a collision and points you to xql.

Use it from Claude Code

xshape was built for AI coding agents as much as for people, so the repo ships an official Claude Code skill under skills/xshape/. It teaches an agent the six verbs, the shared addressing dialect, the three boundary rules (geometry only, explicit separators, no silent drop or combine), and — with a tidyr/pandas/Miller translation table — how to reach for xshape instead of a pandas melt the moment a reshape is needed. Drop it into your personal skills directory:

mkdir -p ~/.claude/skills/xshape
for f in SKILL.md reference.md; do
  curl -fsSL "https://raw.githubusercontent.com/excelano/xshape/main/skills/xshape/$f" \
    -o ~/.claude/skills/xshape/$f
done

Or, from a clone of this repo, cp -r skills/xshape ~/.claude/skills/.

License

MIT. Authored by David M. Anderson, with AI assistance.

About

Reshape for tabular data — pivot, unpivot, split, merge, explode, transpose a CSV/DSV without changing, filtering, or aggregating a value.

Resources

License

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors