Terminal GuideTerminal Guide

choose

Modern CLI
macOSLinuxWindows
Rust

Human-friendly cut/awk alternative.

Official Website

Features

Simple SyntaxNegative IndicesField RangesFast
Replaces
cut

Installation

Homebrew
brew install choose
Cargo (Rust)
cargo install choose

Why use choose?

choose is a modern, intuitive alternative to traditional tools like cut and awk. It provides a simpler syntax for field selection and manipulation, making data extraction tasks more straightforward and less error-prone.

Human-Friendly Syntax

Intuitive field selection without complex regex patterns. Easy to read and remember.

Negative Indices Support

Select fields from the end of the line using negative indices, just like Python lists.

Flexible Delimiters

Support for any delimiter including spaces, tabs, colons, and custom delimiters.

Fast Performance

Written in Rust for blazing-fast execution, even on large datasets.

Installation

Using Homebrew (macOS/Linux)

Installation
brew install choose

Using Cargo (Rust)

Installation
cargo install choose

Verify Installation

Verification
choose --version

Basic Usage

Simple Field Selection

Basic Examples
# Select a single field (0-indexed)
echo "apple banana cherry date" | choose 1
# Output: banana

# Select multiple non-consecutive fields
echo "apple banana cherry date" | choose 0 2
# Output: apple cherry

# Select a range of fields
echo "apple banana cherry date" | choose 0:2
# Output: apple banana cherry

# Select until the end
echo "apple banana cherry date" | choose 1:
# Output: banana cherry date

Using Negative Indices

Negative Indices
# Select the last field
echo "apple banana cherry date" | choose -1
# Output: date

# Select everything except the last field
echo "apple banana cherry date" | choose 0:-1
# Output: apple banana cherry

# Select from second-to-last to end
echo "apple banana cherry date" | choose -2:
# Output: cherry date

Custom Delimiters

Delimiter Examples
# Using colon as delimiter (common for /etc/passwd)
echo "root:x:0:0:root:/root:/bin/bash" | choose -d: 0 4
# Output: root root

# Using comma as delimiter (CSV files)
echo "John,Doe,john@example.com,Engineer" | choose -d, 0 2
# Output: John john@example.com

# Using tab as delimiter
echo -e "name\tage\tcity" | choose -d$'\t' 0 2
# Output: name city

Common Options

OptionDescriptionExample
-d, --delimiterSpecify field delimiterchoose -d: 0
-f, --output-delimiterSpecify output delimiterchoose -f, 0 2
-r, --rangesOutput ranges infochoose -r 0:2
-n, --non-greedyNon-greedy separator matchingchoose -n 0
--output-field-separatorAlternative output separator syntaxchoose --output-field-separator=- 0 2

Practical Examples

Processing Log Files

Log Processing
# Extract timestamp and error message from logs
cat /var/log/app.log | choose 0 1 -d' '
# Output: 2024-01-20 ERROR

# Get only the status code from access logs
cat /var/log/access.log | choose -d' ' 8
# Output: 200

# Extract multiple important fields from logs
cat /var/log/app.log | choose -d' ' 0 1 2 3
# Output: 2024-01-20 12:34:56 ERROR message

Working with System Files

System Files
# Extract usernames from /etc/passwd
cat /etc/passwd | choose -d: 0
# Output: root, daemon, bin, ...

# Get user home directories
cat /etc/passwd | choose -d: 0 5
# Output: root /root, daemon /usr/sbin, ...

# Extract all fields except shell for a user
grep "^john:" /etc/passwd | choose -d: 0:-1
# Output: john:x:1000:1000:John Doe:/home/john

CSV Data Extraction

CSV Processing
# Extract name and email from CSV
cat users.csv | choose -d, 0 2
# Output: John john@example.com

# Get last two columns (excluding header)
tail -n +2 data.csv | choose -d, -2:
# Output: [last two columns]

# Select specific columns with custom output
cat records.csv | choose -d, -f' | ' 1 3 4
# Output: [field1] | [field3] | [field4]

Text Processing Pipelines

Pipeline Examples
# Extract command names from history
history | choose 1
# Output: ls, cd, grep, ...

# Process network connections
netstat -an | choose 3 4 5
# Output: [local address] [remote address] [state]

# Get file sizes and permissions
ls -la | choose 0 4 8
# Output: -rw-r--r-- 1024 file.txt

Tips and Tricks

Creating Useful Aliases

Shell Aliases
# ~/.bashrc or ~/.zshrc

# Extract usernames from passwd file
alias getusers='cat /etc/passwd | choose -d: 0'

# Get file permissions and names
alias perms='ls -la | choose 0 8'

# Extract URLs from text
alias geturls='choose -d/ 2 3'

# Process CSV with common delimiter
alias csv='choose -d,'

Comparison with Traditional Tools

Tool Comparison
# Traditional cut approach (complex)
echo "a:b:c" | cut -d: -f1,3

# Using choose (simpler)
echo "a:b:c" | choose -d: 0 2

# Traditional awk approach (verbose)
echo "a b c" | awk '{print $1, $3}'

# Using choose (cleaner)
echo "a b c" | choose 0 2

# With different output delimiter
echo "a b c" | choose -f: 0 2
# Output: a:c

Advanced Field Selection

Advanced Selection
# Select all but skip one field
echo "1 2 3 4 5" | choose 0 2 4
# Output: 1 3 5

# Combine positive and negative indices
echo "a b c d e" | choose 0 2 -1
# Output: a c e

# Multiple ranges
echo "one two three four five six" | choose 0:1 3: -d' '
# Output: one two four five six

choose vs cut vs awk

Featurecutawkchoose
Learning curveModerateSteepGentle
Negative indicesNoNoYes
Complex patternsLimitedAdvancedModerate
SpeedFastGoodVery fast
Use case fitSimple extractionsComplex transformationsDaily field selection

Tips

  • choose uses 0-based indexing like Python and most programming languages, making it intuitive for developers
  • The default delimiter is whitespace, which automatically collapses multiple spaces or tabs
  • Negative indices work similarly to Python slicing, making the tool more intuitive for modern developers
  • For CSV files with quoted fields containing delimiters, consider using more specialized tools like Miller or xsv
  • You can chain choose with other tools to build powerful data processing pipelines
  • Use --ranges to debug your field selections before committing to processing large files
Written by Dai AokiPublished: 2026-01-20

Related Articles

Explore More