Skip to main content

A TUI paging application with enhanced support for tabular data and real-time streaming

Project description

Nothing-less (nless)

Nless is a TUI paging application (based on the awesome Textual library) with vi-like keybindings. Nless has enhanced functionality for parsing tabular data:

  • inferring file delimiters
  • delimiter swapping on the fly
  • regex-based parsing of raw logs into tabular data using Python's regex engine
  • filtering
  • sorting
  • searching
  • real-time event parsing.

Getting started

Dependencies

  • python>=3.13
    OR
  • brew

Installation

pip install nothing-less
OR
brew install mpryor/tap/nless

Usage

  • pipe the output of a command to nless to parse the output $COMMAND | nless
  • read a file with nless nless $FILE_NAME
  • redirect a file into nless nless < $FILE_NAME
  • Once output is loaded, press ? to view the keybindings

Why?

As a kubernetes engineer, I frequently need to interact with streaming tabular data. k get pods -w, k get events -w, etc. I want a TUI tool to quickly dissect and analyze this data - and none of the existing alternatives had exactly what I wanted:

  • streaming support
  • delimiter inference - I don't want to do a bunch of work to tell the program what type of data it's viewing, I want it to infer it if possible
  • vi-like keybindings So I decided to build my own tool, integrating some of my favorite features that I've seen in other similar tools.

Goals

This project is not meant to be a replacement/competitor for any of the tools mentioned in the alternatives section at the end. Instead, it's meant to bring its own unique set of features to compliment your workflow.

  • UX:
    • vi-like keybindings, familiar to any VIM user
    • minimize the number of keypresses to analyze a dataset
  • Kubernetes support:
    • support for K8s usecases out of the box - such as parsing data streams from kubectl
  • Tabular data toolkit:
    • broad support for a variety of use-cases analyzing,filtering,sorting, and searching tabular data
    • converting data streams into tabular data, such as JSON log parsing

Demos

Basic functionality

The below demo shows basic functionality:

  • starting with a search /
  • applying that search &
  • filtering the selected column by the value within the selected cell F
  • swapping the delimiter D (raw and ,)

asciicast

Streaming functionality

The below demo showcases some of nless's features for handling streaming input, and interacting with unknown delimitation:

  • The nless view stays up-to-date as new log lines arrive on stdin (allows pipeline commands, or redirecting a file into nless)
  • Showcases using a custom (Python engine) regex, example - {(?P<severity>.*)}\((?P<user>.*)\) - (?P<message>.*) - to parse raw logs into tabular fields.
  • Sorts, filters, and searches on those fields.
  • Flips the delimiter back to raw, sorts, searches, and filters on the raw logs

asciicast

Features & Functionality

Buffers:

  • All mutating actions will apply the action by replicating the current "buffer". This allows you to jump up and down the stack to see how you've analyzed your data.
  • [1-9] - will select the buffer at the index corresponding to the input number
  • L - selects the next buffer
  • H - select the previous buffer
  • q - closes the current active buffer, or the program if all buffers are closed
  • N - creates a new buffer from the original data

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 - to select a column to jump the cursor to

Column visibility

  • C - will prompt for a regex filter to selectively display columns, or all to see all columns. TIP: use a non-existing column (none, for example) to only see the current pivots/count
  • > - will move the current column one to the right
  • < - will move the current column one to the left

Pivoting

  • U - will mark the selected column as part of a composite key to group records by, adding a count column pinned to the left
    • enter - pressing enter while the cursor is over one of the composite key columns will "dive in" to the data set behind the pivot - applying the composite key as a filter in a new buffer

Filtering:

  • f - will filter the current column and prompt for a filter
  • F - will filter the current column by the highlighted cell
  • | - will filter ALL columns and prompt for a filter
  • & - applies the current search as a filter across all columns

Searching:

  • / - will prompt for a search value and jump to the first match
  • * - will search all columns for the current highlighted cell value
  • n - jump to the next match
  • p - jump to previous match

Output:

  • W - will prompt for a file to write the current buffer to. - can be used to write to stdout, allowing you to use nless inside of a command chain cat $MY_FILE.txt | nless | grep -i active for example.
  • y - copies the contents of the currently highlighted cell to the clipboard

Shell Commands:

  • ! - run a shell command and pipe its output into a new buffer for analysis

Tail Mode:

  • t - toggle tail mode, which keeps the cursor at the bottom as new data arrives (useful for streaming input)

Unparsed Logs:

  • ~ - view logs that did not match the current delimiter, useful for spotting malformed or unexpected lines

Help:

  • ? - show the help screen with all keybindings

Sorting:

  • s - toggles ascending/descending sort on the current column

json:

  • in addition to the json delimiter that can be set per session or per column, there's also support for json actions:
  • J - will prompt you to select a json field, under the current cell, to add as a column for further filtering/sorting/etc

Delimiter/file parsing:

  • By default, nless will attempt to infer a file delimiter from the first few rows sent through stdin. It uses common delimiters to start - ,, , |, \t, etc.

  • D - you can use D to explicitly swap the delimiter on the fly. Just type in one of the common delimiters above, and the rows will be re-parsed into a tabular format.

  • D - alternatively, you can pass in a regex with named capture groups. Those named groups will become the tabular columns, and each row will be parsed and split across those groups. Example {(?P<severity>.*)}\((?P<user>.*)\) - (?P<message>.*)

  • D - additionally you can just pass the word raw to see the raw lines behind the data. You can still sort, filter, and search the raw lines.

  • D - pass the word json to parse the first set of keys from each JSON line (or read the whole buffer in as a JSON object/list)

  • D - last, you can pass a delimiter value of (two spaces). This will parse text that has been delimited utilizing multiple spaces, while preserving values that have a single space. This is most commonly useful for parsing kubernetes output (kubectl get pods -w), for example.

  • d - transforms a column into more columns using a columnar delimiter. Supports three modes:

    • json — extracts keys from JSON objects in the selected column into new columns
    • A regex with named capture groups — each group becomes a new column (e.g. (?P<host>[^:]+):(?P<port>\d+))
    • Any string delimiter — splits the column's values by the given string (e.g. :, -, etc.)

Contributing

Contributions are welcome! Please open an issue or a pull request - check out the contributing guidelines for more information.

Alternatives

Shout-outs to all of the below wonderful tools! If my tool doesn't have what you need, they likely will:

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

nothing_less-1.0.0.tar.gz (39.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

nothing_less-1.0.0-py3-none-any.whl (41.3 kB view details)

Uploaded Python 3

File details

Details for the file nothing_less-1.0.0.tar.gz.

File metadata

  • Download URL: nothing_less-1.0.0.tar.gz
  • Upload date:
  • Size: 39.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for nothing_less-1.0.0.tar.gz
Algorithm Hash digest
SHA256 5d9e227e9fae04e429fcfcda203052f4cc036e89f90dc126ccd448efca60db69
MD5 4c184351773d8675fe79bb1b603f67b5
BLAKE2b-256 f22be3c20c5abcca161204f0d182beb5e3c30904d3cc2d77a9fc7df00451566e

See more details on using hashes here.

File details

Details for the file nothing_less-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: nothing_less-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 41.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for nothing_less-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b7e4b835a6464d46e1002d870d30d2f1c64089d2960373caa340d4362770fbec
MD5 3e6ff5b1a8dc715aa1d15e2d9abfa8fd
BLAKE2b-256 1450b9d096242b9e1437d4394364bd87443479bd5d7360f2b2a8446e1f46043e

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page