An open API service indexing awesome lists of open source software.

https://github.com/mpryor/nothing-less

A TUI pager with advanced support for tabular data, inferring/swapping delimiters, and real-time event parsing.
https://github.com/mpryor/nothing-less

cli datawrangling devops-tools json kubernetes python spreadsheet tabular-data terminal terminal-based textual tsv tui

Last synced: 26 days ago
JSON representation

A TUI pager with advanced support for tabular data, inferring/swapping delimiters, and real-time event parsing.

Awesome Lists containing this project

README

          

nless


excel for your logs — pipe in **anything**, wrangle it into columns.


nless demo — search, filter, sort, and pivot streaming K8s events


PyPI
Python
License: MIT
CI


Documentation ·
Tutorials ·
Keybindings ·
Install

**nless** is a TUI pager for exploring and analyzing tabular data with vi-like keybindings, built on [Textual](https://textual.textualize.io/). Pipe in anything and nless infers the structure so you can filter, sort, pivot, and reshape without config. Works with CSV, TSV, JSON, logs, and any delimited output.

## Installation

```bash
pipx install nothing-less
```

or

```bash
brew install mpryor/tap/nless
```

Requires Python 3.13+ for pipx/pip installs. You can also use `pip install nothing-less` if you prefer. The Homebrew formula manages its own Python dependency.

## Usage

```bash
kubectl get events -w | nless # stream K8s events
cat access.log | nless # explore log files
nless data.csv # open CSV directly
nless < output.json # redirect a file
```

Press `?` inside nless to view all keybindings.

## Demos

CSV — open, search, filter, sort, pivot


nless CSV demo — open a file, search, filter, sort, and pivot

JSON — pipe in API responses, auto-detect keys as columns


nless JSON demo — auto-detect JSON keys as columns

Regex — parse raw logs into columns with named capture groups


nless regex demo — parse raw logs into structured columns

Pipe mode — use nless as a pipeline stage


nless pipe mode — filter, transform, and output as JSON

## Why nless?

I frequently need to explore streaming tabular data: server logs, kubectl output, CSV exports, CI pipelines. None of the existing tools had exactly the feature set I wanted, so I built nless.

- **Zero config** — pipe in anything and nless infers the structure.
- **Stream-native** — built for data that's still arriving, with streaming features like tail mode, arrival timestamps, and time window filtering.
- **Vi-native** — if you know Vim, nless should feel familiar. If you don't, choose from the other built-in keymaps or build your own.
- **Mouse-friendly** — click column headers to sort, double-click pivot rows to drill in, right-click for context menus, navigate via the menu bar.
- **One tool, many formats** — CSV, TSV, JSON, space-aligned, regex, raw. Switch between them without leaving the pager.

## Features

- **Delimiter inference & swapping** — auto-detects CSV, TSV, space-aligned, JSON, and more. Swap with `D`, or use regex with named capture groups.
- **Filtering & searching** — filter by column, cell value, or search match. Exclude rows. Full-text search with match navigation.
- **Sorting & pivoting** — one-key sort on any column. Group by composite key with summary view and drill-in.
- **Streaming & tail mode** — live-updating as new data arrives, with arrival timestamps and time window filtering.
- **JSON & log parsing** — extract nested JSON fields into columns. Parse unstructured logs with regex.
- **Pipe mode** — use nless as a pipeline stage with `Q` to pipe and exit, or `--no-tui` for batch mode.

All features

- **Buffers** — mutating actions create a new buffer, letting you jump up and down your analysis history.
- **Delimiter swapping** — swap between CSV, TSV, space-aligned, JSON, regex with named capture groups, and raw mode with `D`.
- **Column delimiters** — split a column into more columns using JSON, regex, or string delimiters with `d`.
- **Filtering** — filter by column (`f`/`F`), exclude (`e`/`E`), across all columns (`|`), or from a search (`&`).
- **Sorting** — toggle ascending/descending sort on any column with `s`.
- **Searching** — search (`/`), search by cell value (`*`), navigate matches (`n`/`p`).
- **Pivoting** — group records by composite key with `U`, focused summary view, dive into grouped data with `enter`.
- **Column management** — show/hide columns (`C`), reorder columns (`<`/`>`).
- **JSON extraction** — promote nested JSON fields to columns with `J`.
- **Shell commands** — run a shell command and pipe its output into a new buffer with `!`.
- **Tail mode** — keep the cursor at the bottom as new data arrives with `t`.
- **Output** — write buffer contents to a file or stdout (`W`), copy cell values (`y`).
- **Themes** — 10 built-in color themes (Dracula, Nord, Gruvbox, etc.) plus custom theme support, switch with `T`.
- **Arrival timestamps** — every row records when it was received. Toggle the `_arrival` column with `A`.
- **Time window filtering** — show only recent rows with `@` (e.g. `5m`, `1h`). Append `+` for rolling windows. Prefix with a column name to filter by parsed timestamps (e.g. `timestamp 5m`).
- **Timestamp parsing & conversion** — auto-detects datetime columns (epoch, ISO 8601, syslog, etc.) for type-aware sorting. Convert formats with `@colname -> target` (epoch, iso, relative, strftime, with optional timezone conversion). Also available from the CLI with `--format-timestamp` / `-F` for batch pipelines.
- **Raw pager mode** — `--raw` or auto-detected. A fast virtual-rendering pager for unstructured text, handling million-line files without columnar overhead.
- **Excluded lines** — view lines that failed to parse or were removed by filters with `~`, with chained accumulation across buffers.
- **Pipe mode** — use nless as a pipeline stage. Interactive exploration with `Q` to pipe and exit, batch mode with `--no-tui`, or `--tui` to force interactive mode.
- **Mouse support** — click column headers to sort, double-click pivot rows to drill in, right-click for context menus, navigate via the menu bar.
- **Merge files** — combine multiple files into a single view with a `_source` column using `--merge`.

Full keybinding reference

**Buffers**:
- `[1-9]` - select the buffer at the corresponding index
- `L` - select the next buffer
- `H` - select the previous buffer
- `q` - close the current active buffer, or the program if all buffers are closed
- `Q` - pipe current buffer to stdout and exit immediately (pipe mode shortcut)
- `N` - create a new buffer from the original data
- `r` - rename the current buffer
- `M` - merge the current buffer with another buffer

**Groups**:
- `}` - switch to the next buffer group
- `{` - switch to the previous buffer group
- `R` - rename the current group
- `O` - open a file in a new buffer group

**Navigation**:
- `h` - move cursor left
- `l` - move cursor right
- `j` - move cursor down
- `k` - move cursor up
- `0` - jump to first column
- `$` - jump to final column
- `g` - jump to first row
- `G` - jump to final row
- `w` - move cursor right
- `b`/`B` - move cursor left
- `ctrl+u` - page up
- `ctrl+d` - page down
- `c` - select a column to jump the cursor to

**Column visibility**:
- `C` - prompt for a regex filter to selectively display columns, or `all` to see all columns
- `m` - pin or unpin the current column to the left side of the screen
- `>` - move the current column one to the right
- `<` - move the current column one to the left
- `A` - toggle the `_arrival` metadata column showing when each row was received

**Pivoting**:
- `U` - mark the selected column as part of a composite key to group records by, adding a `count` column pinned to the left
- `enter` - while over a composite key column, dive into the data behind the pivot

**Filtering**:
- `f` - filter the current column and prompt for a filter
- `F` - filter the current column by the highlighted cell
- `e` - exclude from the current column and prompt for a value
- `E` - exclude the current column by the highlighted cell
- `|` - filter ALL columns and prompt for a filter
- `&` - apply the current search as a filter across all columns
- `@` - set a time window to show only recent rows (e.g. `5m`, `1h`); append `+` for rolling; prefix with column name for column-based filtering (e.g. `timestamp 5m`); use `->` for format conversion (e.g. `timestamp -> relative`)

**Searching & Highlighting**:
- `/` - prompt for a search value and jump to the first match
- `*` - search all columns for the current highlighted cell value
- `n` - jump to the next match
- `p` - jump to previous match
- `+` - pin the current search as a persistent highlight
- `-` - navigate or manage pinned highlights

**Output**:
- `W` - prompt for a file to write the current buffer to (`-` writes to stdout)
- `y` - copy the contents of the currently highlighted cell to the clipboard

**Shell Commands**:
- `!` - run a shell command and pipe its output into a new buffer

**Tail Mode**:
- `t` - toggle tail mode
- `x` - reset new-line highlights

**Sessions & Views**:
- `S` - open the session menu (save, load, rename, delete)
- `v` - open the view menu (save, load, rename, delete)

**Themes & Keymaps**:
- `T` - open the theme selector
- `K` - open the keymap selector

**Excluded Lines**:
- `~` - view excluded lines (parse failures + filtered rows), with chained accumulation

**Sorting & Aggregations**:
- `s` - toggle ascending/descending sort on the current column
- `a` - show column aggregations (count, distinct, sum, avg, min, max)

**JSON**:
- `J` - select a JSON field under the current cell to add as a column

**Delimiter/file parsing**:
- `D` - swap the delimiter on the fly (common delimiters, regex with named capture groups, `raw`, `json`, or ` ` for double-space aligned output like kubectl)
- `d` - split a column into more columns using a columnar delimiter (`json`, regex with named capture groups, or any string)
- `P` - auto-detect a known log format and apply it as a regex delimiter

**Help**:
- `?` - show the help screen with all keybindings

**Mouse**:
- Left-click column headers to sort
- Double-click pivot rows to drill in
- Right-click cells, headers, tabs, or groups for context menus
- Click buffer tabs or group bar to switch
- Menu bar for mouse-driven access to all actions

See the [full keybinding reference](https://mpryor.github.io/nothing-less/keybindings/) and [tutorials](https://mpryor.github.io/nothing-less/tutorials/) for more.

## Contributing

Contributions are welcome! See the [contributing guidelines](CONTRIBUTING.md) for details.

## Alternatives

If nless doesn't have what you need, check out these other great tools:

| | [nless](https://github.com/mpryor/nothing-less) | [VisiData](https://www.visidata.org/) | [csvlens](https://github.com/YS-L/csvlens) | [lnav](https://github.com/tstack/lnav) | [Toolong](https://github.com/Textualize/toolong) |
|---|:---:|:---:|:---:|:---:|:---:|
| **Focus** | Tabular data pager | Data multitool | CSV viewer | Log navigator | Log viewer |
| **Language** | Python | Python | Rust | C++ | Python |
| Streaming / stdin | :white_check_mark: | :heavy_minus_sign: | :heavy_minus_sign: | :white_check_mark: | :white_check_mark: |
| Delimiter inference | :white_check_mark: | :heavy_minus_sign: | :heavy_minus_sign: | :x: | :x: |
| Vi keybindings | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :x: |
| Filtering | :white_check_mark: | :white_check_mark: | :heavy_minus_sign: | :white_check_mark: | :x: |
| Sorting | :white_check_mark: | :white_check_mark: | :white_check_mark: | :heavy_minus_sign: | :x: |
| Pivoting / grouping | :white_check_mark: | :white_check_mark: | :x: | :heavy_minus_sign: | :x: |
| JSON parsing | :white_check_mark: | :white_check_mark: | :x: | :white_check_mark: | :heavy_minus_sign: |
| Log format detection | :white_check_mark: | :x: | :x: | :white_check_mark: | :heavy_minus_sign: |
| Regex column parsing | :white_check_mark: | :white_check_mark: | :x: | :white_check_mark: | :x: |
| Pipe mode | :white_check_mark: | :white_check_mark: | :heavy_minus_sign: | :heavy_minus_sign: | :x: |
| Raw text pager | :white_check_mark: | :heavy_minus_sign: | :x: | :white_check_mark: | :white_check_mark: |
| Themes | :white_check_mark: | :white_check_mark: | :heavy_minus_sign: | :white_check_mark: | :x: |
| SQL queries | :x: | :x: | :x: | :white_check_mark: | :x: |
| Python expressions | :x: | :white_check_mark: | :x: | :x: | :x: |
| Timestamp parsing | :white_check_mark: | :x: | :x: | :white_check_mark: | :white_check_mark: |
| Multi-file merge | :white_check_mark: | :white_check_mark: | :x: | :white_check_mark: | :white_check_mark: |

:white_check_mark: full support · :heavy_minus_sign: partial · :x: not supported