Introduction
Nushell (nu) is a modern shell that treats data as structured information rather than plain text. It brings spreadsheet-like data manipulation to the command line with built-in support for JSON, CSV, YAML, and other formats.
Installation
Using Package Managers
# macOS with Homebrew
brew install nushell
# Windows with Winget
winget install nushell
# Linux with Snap
snap install nushell
# Cargo (Rust package manager)
cargo install nu
From GitHub Releases
Download pre-built binaries from GitHub releases.
Basic Concepts
Structured Data Philosophy
Unlike traditional shells that work with text streams, Nushell works with structured data:
- Everything is a table or structured data
- Pipelines pass structured data between commands
- Built-in understanding of common data formats
Starting Nushell
nu
Core Commands and Navigation
This would be a basic commands, that all seasond developers are know, but the way that shell treats its output would suprise most of us. I leave this commands for the newcomers, who want to learn and to master basic commands.
File System Navigation
# List directory contents (structured output)
ls
# Change directory
cd /path/to/directory
# Present working directory
pwd
# Go back to previous directory
cd -
# Go to home directory
cd ~
File Operations
# Create files
touch file.txt
"Hello World" | save hello.txt
# Copy files
cp source.txt destination.txt
# Move/rename files
mv oldname.txt newname.txt
# Remove files
rm file.txt
# Create directories
mkdir new-folder
# Remove directories
rmdir empty-folder
rm -rf folder-with-contents
Working with Structured Data
Viewing Data
# View file contents
open data.json
open data.csv
open data.yaml
# View with pagination
open large-file.txt | less
# Get file info
ls | get name size modified
Data Manipulation Commands
select
- Choose specific columns
ls | select name size
ps | select name pid cpu
where
- Filter rows
ls | where size > 1mb
ps | where cpu > 50
ls | where name =~ "\.txt$" # regex match
sort-by
- Sort data
ls | sort-by size
ls | sort-by modified --reverse
group-by
- Group data
ls | group-by type
ps | group-by user
get
- Extract specific values
ls | get 0 # First row
ls | get name # All names
ls | get name.0 # First name
length
- Count items
ls | length
ps | where name =~ "python" | length
first
and last
- Get specific rows
ls | first 5
ps | last 3
skip
and take
- Pagination
ls | skip 10 | first 5 # Skip first 10, take next 5
Data Formats
JSON
# Read JSON
open data.json
# Create JSON
{name: "John", age: 30} | to json
# Pretty print JSON
open data.json | to json --indent 2
CSV
# Read CSV
open data.csv
# Create CSV
[{name: "Alice", age: 25}, {name: "Bob", age: 30}] | to csv
# Convert other formats to CSV
open data.json | to csv
YAML
# Read YAML
open config.yaml
# Create YAML
{database: {host: "localhost", port: 5432}} | to yaml
Variables and Configuration
Variables
# Set variables
let name = "John"
let numbers = [1, 2, 3, 4, 5]
let config = {host: "localhost", port: 8080}
# Use variables
echo $name
echo $numbers
echo $config.host
Environment Variables
# View environment
env
# Set environment variable
$env.MY_VAR = "value"
# Use environment variable
echo $env.HOME
echo $env.PATH
Configuration
# View current config
config
# Edit config file
config nu
# Set config values
config set table.mode rounded
Advanced Features
Custom Commands
# Define a custom command
def greet [name: string] {
$"Hello, ($name)!"
}
# Use the command
greet "World"
# Command with flags
def search [pattern: string, --case-sensitive] {
if $case_sensitive {
ls | where name =~ $pattern
} else {
ls | where name =~ $"(?i)($pattern)"
}
}
Aliases
# Create aliases
alias ll = ls -la
alias gs = git status
alias la = ls -a
# View aliases
alias
Loops and Conditionals
# For loop
for file in (ls | get name) {
echo $"Processing ($file)"
}
# Each (functional approach)
ls | each { |row| echo $"File: ($row.name)" }
# Conditional
if (ls | length) > 10 {
echo "Many files"
} else {
echo "Few files"
}
Error Handling
# Try-catch equivalent
try {
open nonexistent.txt
} catch {
echo "File not found"
}
# Default values
open config.json | get database.port? | default 3000
Working with External Commands
Running External Commands
# Run external commands
^ls -la
^git status
^python script.py
# Capture output as structured data
^ps aux | from ssv # Space-separated values
Parsing External Command Output
# Parse various formats
^kubectl get pods -o json | from json
^docker ps --format json | lines | each { from json }
Useful Patterns and Examples
Log Analysis
# Parse log files
open server.log
| lines
| parse "{timestamp} {level} {message}"
| where level == "ERROR"
| group-by level
| length
System Monitoring
# Monitor processes
ps | where cpu > 80 | sort-by cpu --reverse
# Check disk usage
ls | where type == dir | insert size_mb { |row| du $row.name | get physical | math sum | $in / 1mb }
Data Processing
# CSV data analysis
open sales.csv
| group-by region
| each { |group|
{
region: $group.0.region,
total_sales: ($group | get sales | math sum),
avg_sales: ($group | get sales | math avg)
}
}
Git Integration
# Git status in structured format
def git-status [] {
^git status --porcelain | lines | parse "{status} {file}"
}
# Branch information
def git-branches [] {
^git branch -v | lines | parse --regex "(?<current>[\*\s])\s+(?<name>\S+)\s+(?<hash>\S+)\s+(?<message>.*)"
}
Configuration and Customization
Startup Configuration
Create ~/.config/nushell/config.nu
:
# Custom prompt
$env.PROMPT_COMMAND = {
let path = ($env.PWD | str replace $env.HOME "~")
$"(ansi green)($path)(ansi reset) > "
}
# Custom aliases
alias ll = ls -la
alias grep = rg
Custom Completions
# Add to config.nu
def "nu-complete git-branches" [] {
^git branch | lines | each { |line| $line | str trim | str replace "* " "" }
}
extern "git checkout" [
branch?: string@"nu-complete git-branches"
]
Performance Tips
- Use structured commands instead of external parsing when possible
# Good
ls | where size > 1mb
# Less efficient
^ls -la | from ssv | where size > 1mb
- Pipeline efficiently
# Filter early in pipeline
ls | where type == file | where size > 1mb | sort-by size
- Use built-in commands for data formats
# Built-in JSON parsing is faster
open data.json | get users.0.name
Debugging and Help
Getting Help
# General help
help
# Command help
help ls
help where
help config
# List all commands
scope commands
Debugging
# Debug mode
$env.RUST_LOG = "debug"
# Verbose output
ls --help
# Check command type
which ls
Migration from Traditional Shells
Common Bash → Nu Patterns
# Bash: grep pattern file.txt
# Nu:
open file.txt | lines | where $it =~ "pattern"
# Bash: find . -name "*.txt" | wc -l
# Nu:
ls **/*.txt | length
# Bash: ps aux | grep python
# Nu:
ps | where name =~ "python"
# Bash: cat file.json | jq '.users[0].name'
# Nu:
open file.json | get users.0.name
Conclusion
Nushell represents a paradigm shift in shell design, treating data as first-class citizens. Its structured approach makes data manipulation more intuitive and powerful than traditional text-based shells. Start with basic commands and gradually incorporate more advanced features as you become comfortable with the structured data philosophy.
And as always dont hesitate to leave your thoughts and criticize this article. Cheers!
Top comments (0)