Manipulating delimited tabular data, log files, and stream outputs on the Linux command line has long relied on utilities like cut and awk. However, both venerable tools exhibit noticeable ergonomic drawbacks. Standard cut cannot split on multiple whitespace characters without collapsing them first, lacks support for negative indexing from the end of a line, and cannot reorder fields. Meanwhile, writing multi-argument awk '{print $1, $3}' statements feels verbose for quick terminal one-liners. To solve these friction points, developers built choose. Written in Rust, choose is a fast, human-friendly command-line tool that brings Python-style slice syntax and regex-based field separation to shell data processing.
Why choose Outperforms Standard cut and awk
The choose command was engineered specifically to address common daily pain points encountered when parsing Unix command outputs:
- Python/Rust Slice Syntax: Slice fields using intuitive indices, ranges, and negative steps (e.g.
choose 0for the first column,choose -1for the final column, orchoose 2:5for a range). - Intelligent Whitespace Handling: By default, consecutive tabs and spaces are collapsed into single delimiters, meaning command outputs like
ps auxorls -lcan be sliced immediately without piping throughtr -s ' '. - Field Reordering: Output columns in any custom sequence (such as
choose 3 1 0), a capability impossible with standardcut. - Arbitrary Character Slicing: Toggle character mode (
-c) to extract specific letter ranges from lines. - High Throughput: Benchmarks confirm choose matches or exceeds standard GNU cut throughput on multi-gigabyte dataset streams.
Installing choose on Linux
You can install choose using package managers, Cargo, or precompiled standalone binaries.
Method 1: Installing via Cargo (Universal)
If you have Rust and Cargo installed, compile the latest release directly from crates.io:
cargo install choose
Ensure ~/.cargo/bin is in your active shell $PATH:
choose --version
Method 2: Installing Precompiled Binaries from GitHub
For production servers without compiler tools, download the pre-built tarball from GitHub Releases:
VERSION=$(curl -s https://api.github.com/repos/theryangeary/choose/releases/latest | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\\1/')
wget "https://github.com/theryangeary/choose/releases/download/${VERSION}/choose-x86_64-unknown-linux-musl.tar.gz"
tar -xzf choose-x86_64-unknown-linux-musl.tar.gz
sudo mv choose /usr/local/bin/
sudo chmod +x /usr/local/bin/choose
Method 3: Package Managers (Arch Linux & Homebrew)
On Arch Linux:
yay -S choose
On systems using Linuxbrew:
brew install choose-rust
Basic Field Slicing and Negative Indexing
Using choose is intuitive. It indexes fields starting from zero (0). Piping tabular data into choose extracts specific tokens immediately.
Extracting Single Columns and Last Columns
Consider piping the output of df -h. To isolate filesystem mount points (the final column) and device paths (the first column):
df -h | choose 0 -1
Notice how -1 dynamically references the very last item on every line, regardless of whether lines have varying column counts.
Range Slicing
Choose accepts familiar slice bounds start:end (where end is exclusive, matching Python conventions):
# Extract columns 1 through 3
cat access.log | choose 1:4
# Extract everything from column 2 onwards to the end of the line
cat access.log | choose 2:
# Extract everything up to column 3
cat access.log | choose :3
Specifying Custom Delimiters and Output Separators
While choose defaults to collapsing whitespace, you can define arbitrary input and output delimiters for structured formats like CSV or TSV.
Parsing CSV Data
Use -f (field separator) to set an explicit character or regex delimiter:
choose -f ',' 0 2 4 < users.csv
Customising Output Delimiters
By default, extracted fields are output separated by spaces. You can specify a custom output delimiter using -o:
# Read comma-separated values and output them tab-separated
choose -f ',' -o ' ' 0 1 3 < data.csv
Character Slicing with Character Mode
To slice fixed-width strings by character positions rather than words or delimiters, pass the -c flag:
# Extract the first 10 characters of every line
cat hashes.txt | choose -c :10
# Extract the final 8 characters of every line
cat logs.txt | choose -c -8:
Real-World Pipeline Examples
Here is how choose simplifies everyday system administration pipelines:
1. Inspecting Top Memory Consuming Processes
ps aux --sort=-%mem | choose 1 2 3 -1 | head -n 10
Prints process IDs, CPU percentages, memory percentages, and executable command paths cleanly aligned.
2. Parsing IP Addresses from Network Interfaces
ip -o -4 addr show | choose 1 3
Instantly extracts network adapter names alongside their assigned CIDR network addresses without tedious regex formatting.