Last active
September 30, 2025 03:04
-
-
Save danielbodnar/9ee49f7b25d59f6aafe25339b27e4be8 to your computer and use it in GitHub Desktop.
Revisions
-
danielbodnar revised this gist
Sep 30, 2025 . No changes.There are no files selected for viewing
-
danielbodnar revised this gist
Sep 30, 2025 . No changes.There are no files selected for viewing
-
danielbodnar revised this gist
Sep 30, 2025 . 1 changed file with 1841 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,1841 @@ # Nushell Cheat Sheet ## Table of Contents - [Introduction](#introduction) - [Installation](#installation) - [Basic Concepts](#basic-concepts) - [Data Types](#data-types) - [Working with Strings](#working-with-strings) - [Working with Lists](#working-with-lists) - [Working with Tables](#working-with-tables) - [Files and Filesystem](#files-and-filesystem) - [Custom Commands](#custom-commands) - [Variables](#variables) - [Modules](#modules) - [Environment Variables](#environment-variables) - [Configuration](#configuration) - [Pipelines](#pipelines) - [Control Flow](#control-flow) - [Common Commands](#common-commands) - [Coming from Bash](#coming-from-bash) - [Tips and Tricks](#tips-and-tricks) --- ## Introduction **Nushell (Nu)** is a modern, cross-platform shell that treats everything as structured data. Unlike traditional shells that work with text streams, Nushell works with tables, lists, and records, making data manipulation more intuitive and powerful. ### Key Features - **Cross-platform**: Works on Linux, macOS, BSD, and Windows - **Structured data**: Pipelines use tables, lists, and records instead of plain text - **Built-in data formats**: Native support for JSON, YAML, CSV, TOML, XML, and more - **Type system**: Strongly typed with excellent error messages - **Modern shell**: Built in Rust with performance and safety in mind --- ## Installation ### macOS / Linux #### Homebrew ```shell brew install nushell ``` #### Nix profile ```shell nix profile install nixpkgs#nushell ``` ### Windows ```powershell # User scope (default) winget install nushell # Machine scope (Run as admin) winget install nushell --scope machine ``` ### From Source ```shell # Clone the repository git clone https://github.com/nushell/nushell # Build with cargo cd nushell cargo build --release --features=extra # Or install directly cargo install nu ``` ### Launch Nushell After installing, launch Nu by typing: ```shell nu ``` --- ## Basic Concepts ### Everything is Data Nushell treats command output as structured data. For example, `ls` returns a table, not text: ```nu ls # Returns a table with columns: name, type, size, modified ``` ### Pipelines Like traditional shells, Nushell uses pipes (`|`) to connect commands: ```nu ls | where size > 1kb | sort-by modified ``` ### Types Nushell has a strong type system: - **Primitives**: int, float, string, bool, nothing, binary, date, duration, filesize - **Collections**: list, record, table, range - **Special**: block, closure, glob, cellpath --- ## Data Types ### Integers and Floats ```nu # Integers 42 -17 0x2A # Hexadecimal # Floats 3.14 -0.5 1.23e-4 # Scientific notation ``` ### Strings ```nu # Simple strings "hello" 'world' # String interpolation let name = "Alice" $"Hello, ($name)!" # => "Hello, Alice!" # Multi-line strings "line one line two" ``` ### Booleans ```nu true false ``` ### Nothing (null) ```nu null ``` ### Dates and Durations ```nu # Current date date now # Parse date "2024-01-15" | into datetime # Durations 10sec 5min 2hr 1day 3ms ``` ### Filesizes ```nu 100b # bytes 1kb # kilobytes 5mb # megabytes 2gb # gigabytes 10kib # kibibytes (1024-based) ``` ### Ranges ```nu 1..5 # Range from 1 to 5 1..10..2 # Range from 1 to 10, step by 2 1.. # Open-ended range from 1 ``` ### Lists ```nu [1, 2, 3, 4, 5] ["apple", "banana", "cherry"] [1, "mixed", true, 3.14] # Can contain different types ``` ### Records ```nu { name: "Alice", age: 30, active: true } { x: 10, y: 20 } ``` ### Tables ```nu [[name, age, city]; [Alice, 30, NYC] [Bob, 25, SF] [Carol, 35, LA]] ``` ### Type Conversion ```nu # String to int "42" | into int # String to datetime "2024-01-15" | into datetime # Int to string 42 | into string # To JSON {name: "Alice", age: 30} | to json # From JSON '{"name": "Bob"}' | from json ``` --- ## Working with Strings ### Basic Operations ```nu # Concatenation with interpolation let name = "Alice" $"Hello, ($name)!" # => "Hello, Alice!" # Length "hello" | str length # => 5 # Contains "Hello, world!" | str contains "world" # => true # Starts with / Ends with "hello" | str starts-with "he" # => true "hello" | str ends-with "lo" # => true ``` ### String Manipulation ```nu # Uppercase / Lowercase "hello" | str upcase # => "HELLO" "WORLD" | str downcase # => "world" # Trim whitespace " hello " | str trim # => "hello" # Replace "hello world" | str replace "world" "universe" # => "hello universe" # Split "one,two,three" | split row "," # => ["one", "two", "three"] # Join ["one", "two", "three"] | str join ", " # => "one, two, three" # Substring "Hello World!" | str substring 0..5 # => "Hello" "Hello World!" | str substring 6.. # => "World!" ``` ### Parsing ```nu # Parse structured text "Nushell 0.80" | parse "{shell} {version}" # => ╭───┬─────────┬─────────╮ # => │ # │ shell │ version │ # => ├───┼─────────┼─────────┤ # => │ 0 │ Nushell │ 0.80 │ # => ╰───┴─────────┴─────────╯ ``` ### ANSI Colors ```nu # Color text in terminal $"(ansi red)Error!(ansi reset)" $"(ansi green_bold)Success!(ansi reset)" $"(ansi blue)Info(ansi reset)" ``` --- ## Working with Lists ### Creating Lists ```nu [1, 2, 3, 4, 5] [one two three] # Space-separated 1..10 | to list # From range ``` ### Accessing Elements ```nu let list = [apple banana cherry] $list.0 # => apple $list.1 # => banana $list | get 2 # => cherry ``` ### List Operations ```nu # Length [1, 2, 3] | length # => 3 # Append [1, 2, 3] | append 4 # => [1, 2, 3, 4] # Prepend [1, 2, 3] | prepend 0 # => [0, 1, 2, 3] # Insert at index [foo bar baz] | insert 1 beeze # => [foo, beeze, bar, baz] # Update by index [1, 2, 3, 4] | update 1 10 # => [1, 10, 3, 4] # First / Last [1, 2, 3, 4, 5] | first # => 1 [1, 2, 3, 4, 5] | first 3 # => [1, 2, 3] [1, 2, 3, 4, 5] | last # => 5 [1, 2, 3, 4, 5] | last 2 # => [4, 5] # Skip [1, 2, 3, 4, 5] | skip 2 # => [3, 4, 5] # Reverse [1, 2, 3] | reverse # => [3, 2, 1] # Unique [1, 2, 2, 3, 3, 3] | uniq # => [1, 2, 3] ``` ### Iteration ```nu # Each - iterate over list [1, 2, 3] | each { |x| $x * 2 } # => [2, 4, 6] # Enumerate - add index [a b c] | enumerate # => ╭───┬───────┬──────╮ # => │ # │ index │ item │ # => ├───┼───────┼──────┤ # => │ 0 │ 0 │ a │ # => │ 1 │ 1 │ b │ # => │ 2 │ 2 │ c │ # => ╰───┴───────┴──────╯ # Reduce - fold list to single value [1, 2, 3, 4] | reduce { |item, acc| $acc + $item } # => 10 # Reduce with initial value [3, 8, 4] | reduce --fold 1 { |item, acc| $acc * $item } # => 96 ``` ### Filtering and Searching ```nu # Where - filter by condition [1, 2, 3, 4, 5] | where $it > 3 # => [4, 5] # Any - check if any item matches [1, 2, 3, 4] | any { |x| $x > 3 } # => true # All - check if all items match [1, 2, 3, 4] | all { |x| $x > 0 } # => true # Find - search for element [apple banana cherry] | find ban # => [banana] ``` --- ## Working with Tables ### Creating Tables ```nu # Inline table [[name, age]; [Alice, 30] [Bob, 25] [Carol, 35]] # From records [ {name: Alice, age: 30} {name: Bob, age: 25} {name: Carol, age: 35} ] ``` ### Selecting Columns ```nu # Select specific columns ls | select name size # Reject columns ls | reject type ``` ### Filtering Rows ```nu # Where clause ls | where size > 1kb ls | where type == dir ls | where name =~ ".md" # Regex match ``` ### Sorting ```nu # Sort by column ls | sort-by size ls | sort-by modified --reverse # Sort by multiple columns [[name, age]; [Alice, 30] [Bob, 25] [Carol, 30]] | sort-by age name ``` ### Transforming Tables ```nu # Add column ls | insert bigger_size { |row| $row.size * 2 } # Update column ls | update modified { |row| $row.modified | date format "%Y-%m-%d" } # Rename column ls | rename old_name new_name # Group by ls | group-by type # Transpose [[a, b]; [1, 2] [3, 4]] | transpose ``` ### Aggregations ```nu # Count ls | length # Sum [1, 2, 3, 4] | math sum # Average [1, 2, 3, 4, 5] | math avg # Min / Max [5, 2, 8, 1, 9] | math min [5, 2, 8, 1, 9] | math max ``` --- ## Files and Filesystem ### Navigation ```nu # List files ls ls *.rs # With glob pattern ls **/*.md # Recursive glob # Change directory cd /path/to/dir cd ~ # Home directory cd - # Previous directory # Current directory pwd $env.PWD # As variable ``` ### File Operations ```nu # Create file touch file.txt # Create directory mkdir mydir mkdir -p path/to/nested/dir # Create parents # Copy cp source.txt dest.txt cp -r sourcedir destdir # Recursive # Move/Rename mv old.txt new.txt mv file.txt /other/location/ # Remove rm file.txt rm -r directory # Recursive rm -t file.txt # Move to trash (safer) ``` ### Reading Files ```nu # Read as structured data (auto-detects format) open data.json open data.csv open data.toml # Read as raw text open --raw file.txt # Read specific format open file.json | from json ``` ### Writing Files ```nu # Save structured data {name: "Alice", age: 30} | save person.json # Save as specific format [1, 2, 3] | to csv | save numbers.csv # Append to file "more text" | save --append log.txt # Save raw text "Hello, world!" | save --raw message.txt ``` ### File Information ```nu # File metadata ls -l file.txt # File type "file.txt" | path type # => file or dir # File exists "file.txt" | path exists # => true or false # File size ls file.txt | get size ``` ### Path Operations ```nu # Basename "/path/to/file.txt" | path basename # => file.txt # Dirname "/path/to/file.txt" | path dirname # => /path/to # Extension "/path/to/file.txt" | path extension # => txt # Join paths ["path", "to", "file.txt"] | path join # => path/to/file.txt # Expand tilde "~/documents" | path expand # => /home/user/documents # Parse path "/path/to/file.txt" | path parse ``` ### Glob Patterns ```nu # Find files recursively glob **/*.rs # Find with depth limit glob **/*.md --depth 2 # Watch files and run command on change watch . --glob=**/*.rs {|| cargo test } ``` --- ## Custom Commands ### Basic Command ```nu # Define a command def greet [name: string] { $"Hello, ($name)!" } # Use it greet Alice # => "Hello, Alice!" ``` ### With Default Parameters ```nu def greet [name = "World"] { $"Hello, ($name)!" } greet # => "Hello, World!" greet Alice # => "Hello, Alice!" ``` ### With Flags ```nu def greet [ name: string --shout (-s) # Boolean flag --times (-t): int = 1 # Flag with value ] { let message = if $shout { ($"Hello, ($name)!" | str upcase) } else { $"Hello, ($name)!" } 1..$times | each { $message } | str join "\n" } greet Alice --shout greet Bob --times 3 greet Carol -s -t 2 ``` ### Rest Parameters ```nu # Variable number of arguments def greet-all [...names: string] { $names | each { |name| $"Hello, ($name)!" } } greet-all Alice Bob Carol # => Hello, Alice! # => Hello, Bob! # => Hello, Carol! ``` ### Type Annotations ```nu def process [ count: int # Integer rate: float # Float name: string # String active: bool # Boolean items: list # List config: record # Record ] { # Function body } ``` ### Pipeline Input ```nu # Accept pipeline input def double [] { $in * 2 } 5 | double # => 10 # Typed pipeline input def sum-list []: list<int> -> int { $in | reduce { |item, acc| $acc + $item } } [1, 2, 3, 4] | sum-list # => 10 ``` --- ## Variables ### Immutable Variables ```nu # Basic assignment let x = 42 let name = "Alice" let items = [1, 2, 3] # Cannot reassign # let x = 43 # Error! ``` ### Mutable Variables ```nu # Declare with mut mut count = 0 $count += 1 $count = $count * 2 # Works with all types mut items = [1, 2, 3] $items = ($items | append 4) ``` ### Constants ```nu # Evaluated at parse time const CONFIG_FILE = "config.toml" const MAX_RETRIES = 5 # Can be used in module imports source $CONFIG_FILE ``` ### Variable Scope ```nu let outer = "outside" do { let inner = "inside" print $outer # OK - can access outer scope print $inner # OK } # print $inner # Error - inner is out of scope print $outer # OK ``` ### Shadowing ```nu let x = 10 print $x # => 10 do { let x = 20 print $x # => 20 } print $x # => 10 (unchanged) ``` ### Question Mark Operator ```nu # Return null instead of error if path doesn't exist let value = $record.field?.subfield? # Useful for optional fields let files = (ls) $files.name?.0? # Safe access even if empty ``` --- ## Modules ### Inline Module ```nu module greetings { export def hello [name: string] { $"Hello, ($name)!" } export def goodbye [name: string] { $"Goodbye, ($name)!" } } use greetings hello hello "World" # => "Hello, World!" ``` ### Module Files Create a file `greetings.nu`: ```nu # greetings.nu export def hello [name: string] { $"Hello, ($name)!" } export def goodbye [name: string] { $"Goodbye, ($name)!" } ``` Use it: ```nu use greetings.nu greetings hello "Alice" # Or import specific items use greetings.nu hello hello "Bob" # Or import all use greetings.nu * hello "Carol" goodbye "Dave" ``` ### Module with Environment ```nu # module.nu export-env { $env.MY_VAR = "some value" } export def command [] { print $env.MY_VAR } ``` ### Main Command ```nu # greetings.nu export def main [] { "Greetings and salutations!" } export def hello [name: string] { $"Hello, ($name)!" } ``` Use it: ```nu use greetings.nu greetings # => "Greetings and salutations!" greetings hello Bob # => "Hello, Bob!" ``` --- ## Environment Variables ### Accessing Environment Variables ```nu # Get environment variable $env.PATH $env.HOME $env.USER # List all environment variables $env # Check if variable exists 'PATH' in $env ``` ### Setting Environment Variables ```nu # Set for current session $env.MY_VAR = "value" # Set for single command FOO=BAR some-command # Unset variable hide-env MY_VAR ``` ### Path Configuration ```nu # View path $env.PATH # or $env.Path on Windows # Add to path (prepend) $env.PATH = ($env.PATH | prepend "/new/path") # Add to path (append) $env.PATH = ($env.PATH | append "/another/path") # Using standard library helper use std/util "path add" path add "/my/path" # Prepends by default ``` ### Environment Conversions ```nu # Convert colon-separated string to list $env.ENV_CONVERSIONS = { "XDG_DATA_DIRS": { from_string: {|s| $s | split row (char esep) } to_string: {|v| $v | str join (char esep) } } } ``` --- ## Configuration ### Configuration Files Nushell uses three main configuration files in `$nu.default-config-dir`: 1. **env.nu** - Environment variables (legacy, use config.nu instead) 2. **config.nu** - Main configuration and settings 3. **login.nu** - Loaded only for login shells ### Quick Configuration ```nu # Edit config.nu config nu # Edit env.nu config env # View default config config nu --default | nu-highlight | less -R # View config documentation config nu --doc | nu-highlight | less -R ``` ### Common Settings ```nu # In config.nu # Set default editor $env.config.buffer_editor = "code" # or $env.config.buffer_editor = ["vim", "-n"] # Disable welcome banner $env.config.show_banner = false # Table settings $env.config.table.mode = "rounded" $env.config.table.index_mode = "auto" # History settings $env.config.history.file_format = "sqlite" $env.config.history.max_size = 100_000 # Completion settings $env.config.completions.quick = true $env.config.completions.partial = true # Line editor mode $env.config.edit_mode = "emacs" # or "vi" ``` ### Prompt Configuration ```nu # Simple prompt $env.PROMPT_COMMAND = { $"(pwd | path basename) > " } # Right prompt $env.PROMPT_COMMAND_RIGHT = { date now | format date "%H:%M:%S" } # Transient prompt (after command execution) $env.TRANSIENT_PROMPT_COMMAND = "" $env.TRANSIENT_PROMPT_COMMAND_RIGHT = "" ``` ### LS_COLORS ```nu # Use vivid for LS_COLORS $env.LS_COLORS = (vivid generate molokai) ``` ### Aliases ```nu # In config.nu alias ll = ls -l alias la = ls -a alias g = git ``` ### Startup Scripts Files in autoload directories are loaded automatically: - `$nu.vendor-autoload-dirs` - For vendor/package manager scripts - `$nu.user-autoload-dirs` - For user scripts --- ## Pipelines ### Basic Pipeline ```nu # Chain commands with pipe ls | where size > 1mb | sort-by modified ``` ### Pipeline Variable ```nu # Use $in to refer to pipeline input ls | each { |row| $row.size * 2 } # $in represents the entire input "hello" | $in ++ " world" # => "hello world" ``` ### Multi-line Pipelines ```nu ls | where size > 1kb | sort-by modified | select name size | first 10 ``` ### Tee ```nu # Save intermediate results command1 | tee { save intermediate.txt } | command2 ``` ### Ignoring Output ```nu # Discard output some-command | ignore # Discard stdout and stderr some-command out+err>| ignore ``` --- ## Control Flow ### If-Else ```nu if $x > 10 { "big" } else if $x > 5 { "medium" } else { "small" } ``` ### Match ```nu match $value { 1 => "one", 2 => "two", 3..10 => "several", _ => "many" } ``` ### For Loop ```nu for item in [1, 2, 3, 4] { print $item } # With range for i in 1..10 { print $i } ``` ### While Loop ```nu mut count = 0 while $count < 5 { print $count $count += 1 } ``` ### Loop (infinite) ```nu loop { # Do something if $condition { break } } ``` ### Break and Continue ```nu for i in 1..10 { if $i == 5 { continue # Skip to next iteration } if $i == 8 { break # Exit loop } print $i } ``` ### Try-Catch ```nu try { # Code that might fail open nonexistent.txt } catch { print "File not found" } ``` --- ## Common Commands ### System Information ```nu # System info sys # CPU info sys cpu # Memory info sys mem # Disk info sys disks # Network info sys net # Processes ps # Current user whoami ``` ### Date and Time ```nu # Current date/time date now # Format date date now | format date "%Y-%m-%d %H:%M:%S" # Parse date "2024-01-15" | into datetime # Date arithmetic date now | date add 1day date now | date subtract 2hr ``` ### Math Operations ```nu # Basic math 2 + 3 10 - 5 4 * 6 15 / 3 10 mod 3 # Modulo # Math functions [1, 2, 3, 4, 5] | math sum [1, 2, 3, 4, 5] | math avg [1, 2, 3, 4, 5] | math min [1, 2, 3, 4, 5] | math max [1, 2, 3, 4, 5] | math median # Single value functions -5 | math abs # => 5 2.7 | math floor # => 2 2.3 | math ceil # => 3 2.5 | math round # => 3 9 | math sqrt # => 3 ``` ### HTTP Requests ```nu # GET request http get https://api.example.com/data # POST request http post https://api.example.com/data {key: "value"} # With headers http get https://api.example.com/data --headers {Authorization: "Bearer token"} ``` ### JSON/YAML/TOML ```nu # Parse JSON '{"name": "Alice", "age": 30}' | from json # Convert to JSON {name: "Bob", age: 25} | to json # Pretty print JSON {name: "Carol"} | to json --indent 2 # YAML open config.yaml {key: "value"} | to yaml # TOML open Cargo.toml {key: "value"} | to toml ``` ### Input ```nu # Get user input let name = input "Enter your name: " # Secret input (password) let password = input -s "Enter password: " ``` ### Random ```nu # Random integer random int 1..100 # Random float random float 0..1 # Random boolean random bool # Random UUID random uuid # Random item from list [apple banana cherry] | random ``` --- ## Coming from Bash ### Command Equivalents | Bash | Nu | Description | |------|-----|-------------| | `ls` | `ls` | List files | | `ls -la` | `ls --long --all` or `ls -la` | List all files with details | | `cd <dir>` | `cd <dir>` | Change directory | | `pwd` | `pwd` or `$env.PWD` | Current directory | | `mkdir -p <path>` | `mkdir <path>` | Create directory (parents auto-created) | | `touch file.txt` | `touch file.txt` | Create file | | `cat <file>` | `open --raw <file>` | Display file contents | | `cp <src> <dest>` | `cp <src> <dest>` | Copy file | | `mv <src> <dest>` | `mv <src> <dest>` | Move/rename file | | `rm <file>` | `rm <file>` | Remove file | | `rm -rf <dir>` | `rm -r <dir>` | Remove directory recursively | | `echo $PATH` | `$env.PATH` (Linux/Mac) or `$env.Path` (Windows) | View PATH | | `export FOO=BAR` | `$env.FOO = "BAR"` | Set environment variable | | `echo $FOO` | `$env.FOO` | Use environment variable | | `grep <pattern>` | `where $it =~ <pattern>` or `find <pattern>` | Filter strings | | `find . -name *.rs` | `ls **/*.rs` | Find files recursively | | `which <cmd>` | `which <cmd>` | Locate command | | `man <cmd>` | `help <cmd>` | Get command help | | `command1 && command2` | `command1; command2` | Run commands sequentially | | `>` | `out>` or `\| save` | Redirect output | | `>>` | `out>>` or `\| save --append` | Append output | | `2>&1` | `out+err>\|` or `o+e>\|` | Combine stdout/stderr | ### Bash to Nu Examples ```nu # Bash: for f in *.md; do echo $f; done # Nu: ls *.md | each { |file| $file.name } # Bash: cat file1 file2 | grep pattern # Nu: [file1 file2] | each { open } | str join | find pattern # Bash: export PATH=$PATH:/new/path # Nu: $env.PATH = ($env.PATH | append "/new/path") # Bash: if [ -f file.txt ]; then echo "exists"; fi # Nu: if ("file.txt" | path exists) { "exists" } # Bash: command=$(ls | wc -l) # Nu: let command = (ls | length) ``` --- ## Operators ### Comparison Operators ```nu 5 == 5 # Equal 5 != 3 # Not equal 5 > 3 # Greater than 5 >= 5 # Greater than or equal 3 < 5 # Less than 3 <= 5 # Less than or equal "a" =~ "a" # Regex match "a" !~ "b" # Regex not match 5 in [1,2,3,4,5] # In list ``` ### Math Operators ```nu 3 + 2 # Addition => 5 5 - 2 # Subtraction => 3 3 * 4 # Multiplication => 12 10 / 2 # Division => 5 10 mod 3 # Modulo => 1 2 ** 3 # Exponentiation => 8 ``` ### Boolean Operators ```nu true and false # Logical AND true or false # Logical OR not true # Logical NOT ``` ### String Operators ```nu "hello" ++ " world" # Concatenation => "hello world" "hello" starts-with "he" # true "hello" ends-with "lo" # true "hello" in "hello world" # true ``` ### List Operators ```nu [1 2] ++ [3 4] # Concatenation => [1, 2, 3, 4] [1 2 3] | append 4 # Append => [1, 2, 3, 4] [0 1 2 3] | prepend 4 # Prepend => [4, 0, 1, 2, 3] ``` ### Assignment Operators ```nu mut x = 5 $x += 3 # x = x + 3 $x -= 2 # x = x - 2 $x *= 2 # x = x * 2 $x /= 2 # x = x / 2 $x ++= [4, 5] # Append to list ``` ### Spread Operator ```nu # Spread list elements as separate arguments def greet [...names] { $names | each { |name| $"Hello, ($name)!" } } let guests = ["Alice", "Bob", "Carol"] greet ...$guests # Spreads list as individual arguments ``` --- ## Advanced Topics ### Parallelism ```nu # Run command in parallel for each item ls | par-each { |file| # Process file $file.name | str upcase } # Note: par-each doesn't preserve order ``` ### Error Handling ```nu # Try-catch block try { open nonexistent.txt } catch { print "File not found!" } # Create custom error def my-command [x] { if $x < 0 { error make { msg: "Value must be positive" label: { text: "negative value here" span: (metadata $x).span } } } $x * 2 } ``` ### Background Jobs ```nu # Spawn a background job let job_id = job spawn { sleep 10sec "Job complete" | save result.txt } # List active jobs job list # Kill a job job kill $job_id # Send data to a job "data" | job send $job_id # Receive data from a job job recv ``` ### Dataframes (with Polars) ```nu # Open dataframe let df = polars open data.csv # Select columns $df | polars select [name age] # Filter rows $df | polars filter (polars col age > 30) # Group by and aggregate $df | polars group-by country | polars agg (polars col population | polars sum) # Save dataframe $df | polars save output.parquet ``` ### Plugins ```nu # List installed plugins plugin list # Add a plugin plugin add ~/.cargo/bin/nu_plugin_query # Use plugin commands query web --query 'table' https://example.com ``` ### Hooks Hooks allow running commands at specific events: ```nu # In config.nu $env.config.hooks = { pre_prompt: [{ # Run before each prompt null }] pre_execution: [{ # Run before each command null }] env_change: { PWD: [{|before, after| # Run when directory changes null }] } } ``` ### Overlays ```nu # Create overlay overlay new my-overlay # Activate module as overlay overlay use my-module.nu # Hide overlay overlay hide my-overlay # List active overlays overlay list ``` --- ## Tips and Tricks ### 1. Pipeline Input Variable ```nu # Use $in to refer to pipeline input ls | where $in.size > 1mb "hello" | $in ++ " world" ``` ### 2. Table Display Modes ```nu # Change table mode temporarily ls | table --mode rounded # Available modes: basic, compact, default, heavy, light, # markdown, none, reinforced, rounded, etc. ``` ### 3. Explore Command ```nu # Interactively explore data sys | explore # Explore with specific configuration ls | explore --mode table ``` ### 4. Format Output ```nu # Format as JSON {name: "Alice", age: 30} | to json # Format with custom pattern ls | format pattern "{name} is {size}" # Format date date now | format date "%Y-%m-%d %H:%M:%S" ``` ### 5. Debugging ```nu # View command metadata metadata ls # Explain command explain { ls | where size > 1mb } # Profile execution debug profile { ls | where size > 1mb } # Inspect values let x = [1 2 3] $x | inspect ``` ### 6. History ```nu # View command history history # Search history history | where command =~ "git" # History in SQLite format (default) $env.config.history.file_format = "sqlite" ``` ### 7. Completions ```nu # Custom completions def "nu-complete git-branches" [] { ^git branch | lines | each { |line| $line | str trim } } def "git checkout" [ branch: string@"nu-complete git-branches" ] { ^git checkout $branch } ``` ### 8. Keybindings ```nu # In config.nu $env.config.keybindings = [ { name: my_custom_binding modifier: control keycode: char_t mode: [emacs, vi_normal, vi_insert] event: { send: ExecuteHostCommand cmd: "commandline edit --insert 'test'" } } ] ``` ### 9. Startup Performance ```nu # Fastest startup (no config, no stdlib) nu -n --no-std-lib # No config files nu -n # Custom config nu --config my-config.nu --env-config my-env.nu ``` ### 10. Working with JSON/YAML ```nu # Parse and manipulate JSON open data.json | select name age | where age > 30 # Nested field access open config.json | get server.host # Update nested field open config.json | upsert server.port 8080 | save config.json ``` ### 11. Regular Expressions ```nu # Match "hello123" =~ '\d+' # => true # Extract "Price: $42.50" | parse --regex 'Price: \$(?P<price>[\d.]+)' # Replace "hello world" | str replace --regex '\w+' 'X' # => "X X" ``` ### 12. Cell Paths ```nu # Access nested data let data = {user: {name: "Alice", age: 30}} $data.user.name # => "Alice" # Optional access (doesn't error if missing) $data.user?.email? # => null if doesn't exist # Use in commands open config.json | get server.database.host ``` --- ## Quick Reference Card ### Essential Commands ```nu # File operations ls, cd, pwd, mkdir, touch, rm, cp, mv, open, save # Data manipulation select, where, sort-by, group-by, first, last, take, skip # Iteration each, par-each, reduce, enumerate, filter # Text operations str upcase, str downcase, str trim, str replace, split, parse # Data conversion to json, to yaml, to csv, from json, from yaml, from csv # System ps, sys, whoami, which, date now # Help help <command>, help commands, help --find <term> ``` ### Common Patterns ```nu # Filter and sort ls | where size > 1mb | sort-by size # Group and count ls | group-by type | get file | length # Transform data ls | select name size | update size { |row| $row.size / 1mb } # Chain operations open data.json | where status == "active" | select name email | sort-by name | save filtered.json # Conditional processing ls | each { |file| if $file.size > 1mb { $file.name } } ``` --- ## Resources - **Official Website**: https://www.nushell.sh - **Documentation**: https://www.nushell.sh/book/ - **GitHub**: https://github.com/nushell/nushell - **Discord**: https://discord.gg/NtAbbGn - **Scripts Repository**: https://github.com/nushell/nu_scripts - **Awesome Nu**: https://github.com/nushell/awesome-nu --- ## Configuration Examples ### Minimal config.nu ```nu # Set editor $env.config.buffer_editor = "vim" # Disable banner $env.config.show_banner = false # Table settings $env.config.table.mode = "rounded" # History settings $env.config.history.file_format = "sqlite" $env.config.history.max_size = 100_000 ``` ### Useful Aliases ```nu # In config.nu alias ll = ls -l alias la = ls -a alias lla = ls -la alias g = git alias k = kubectl alias d = docker alias cat = bat # If bat is installed alias grep = rg # If ripgrep is installed ``` ### Custom Prompt ```nu # In config.nu $env.PROMPT_COMMAND = { let dir = (pwd | path basename) let git_branch = (do -i { git branch --show-current } | complete | get stdout | str trim) if ($git_branch | is-empty) { $"($dir) > " } else { $"($dir) [($git_branch)] > " } } ``` --- -
danielbodnar revised this gist
Sep 30, 2025 . No changes.There are no files selected for viewing
-
danielbodnar revised this gist
Sep 30, 2025 . 1 changed file with 66843 additions and 0 deletions.There are no files selected for viewing
-
danielbodnar revised this gist
Sep 20, 2025 . 1 changed file with 286 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -604,6 +604,283 @@ $data | to yaml # Convert to YAML --- ## Database Operations ### In-Memory SQLite (stor) ```nushell # Initialize and manage the in-memory database stor open # Open in-memory database stor reset # Drop all tables # Table management stor create users { # Create table id: int name: string email: string age: int } # Data operations [{id: 1, name: "Alice", email: "[email protected]", age: 30} {id: 2, name: "Bob", email: "[email protected]", age: 25}] | stor insert users # Insert data # Querying with SQL query db "SELECT * FROM users WHERE age > 25" # Updates and deletions stor update users --set "name = 'Alice Smith'" --where "id = 1" stor delete users --where "age < 18" # Delete records # Import/Export stor import database.db # Import SQLite file stor export output.db # Export to SQLite file ``` ### Advanced Database Operations ```nushell # Complex queries query db " SELECT u.name, u.age, COUNT(*) as order_count FROM users u LEFT JOIN orders o ON u.id = o.user_id GROUP BY u.id, u.name, u.age HAVING COUNT(*) > 0 " # Aggregations query db " SELECT age_group, COUNT(*) as count, AVG(age) as avg_age FROM ( SELECT CASE WHEN age < 30 THEN 'young' WHEN age < 50 THEN 'middle' ELSE 'senior' END as age_group, age FROM users ) GROUP BY age_group " # Combining with Nushell pipelines query db "SELECT name, age FROM users" | where age > 25 | sort-by name | update name {|row| $row.name | str upcase} ``` --- ## JSON Processing (jq-style) ### Basic JSON Operations ```nushell # Parse and access JSON data '{"name": "Alice", "age": 30}' | from json | get name # => Alice # Filter arrays '[{"name": "Alice", "age": 30}, {"name": "Bob", "age": 25}]' | from json | where age > 28 # => [{name: "Alice", age: 30}] # Map transformations '[1, 2, 3, 4, 5]' | from json | each {|x| $x * 2} # => [2, 4, 6, 8, 10] ``` ### Advanced JSON Processing ```nushell # Conditional logic '{"name": "Alice", "age": 30}' | from json | if $in.age > 18 { "Adult" } else { "Child" } # String manipulation '{"name": "Alice Smith"}' | from json | get name | split words | get 0 # Grouping and aggregation '[{"category": "A", "value": 10}, {"category": "B", "value": 20}, {"category": "A", "value": 5}]' | from json | group-by --to-table category | update items {|row| $row.items.value | math sum} | rename category total_value # Custom aggregations with reduce '[{"value": 10}, {"value": 20}, {"value": 30}]' | from json | reduce -f 0 {|item, acc| $acc + $item.value} # => 60 ``` ### Nested Data Operations ```nushell # Deep filtering and extraction '{"data": {"values": [1, 2, 3], "nested": {"values": [4, 5, 6]}}}' | from json | get data.values | flatten | where {|x| $x > 3} # Flattening nested structures def "flatten record-paths" [--separator (-s): string = "."] { def helper [ctx?: string] { let input = $in match ($input | describe | str replace '<.*' '') { "record" => { $input | items {|key, value| let path = if $ctx == null { $key } else { [$ctx $key] | str join $separator } $value | helper $path } | flatten } _ => [{path: $ctx, value: $input}] } } $in | helper } # Usage example '{"person": {"name": {"first": "Alice", "last": "Smith"}, "age": 30}}' | from json | flatten record-paths # => [{path: "person.name.first", value: "Alice"}, {path: "person.name.last", value: "Smith"}, {path: "person.age", value: 30}] ``` --- ## Data Analysis (Polars-style) ### DataFrame Operations with Polars ```nushell # Load and inspect data let df = polars open data.csv $df | polars shape # Get dimensions $df | polars first 5 | polars collect # View first 5 rows # Column operations $df | polars with-column (polars col trip_duration | polars str-lengths | polars as duration_length) | polars first 5 | polars collect # Mathematical transformations $df | polars with-column ((polars col trip_duration) / 60.0) # Convert seconds to minutes | polars collect # Filtering $df | polars filter-with ((polars col trip_duration) >= 500) | polars first 10 | polars collect ``` ### Advanced Data Analysis ```nushell # Grouping and aggregation $df | polars filter-with ((polars col store_and_fwd_flag) == "N") | polars group-by vendor_id | polars agg [ (polars col trip_duration | polars mean | polars as avg_duration) (polars col trip_duration | polars max | polars as max_duration) (polars col passenger_count | polars sum | polars as total_passengers) ] | polars sort-by avg_duration | polars collect # Multiple column operations $df | polars select [ (polars col id) (polars col trip_duration | polars as original_duration) ((polars col trip_duration) / 60.0 | polars as duration_minutes) (polars col pickup_longitude | polars round 2 | polars as pickup_lon_rounded) ] | polars first 10 | polars collect # Complex filtering and transformations $df | polars filter-with ( ((polars col trip_duration) > 300) and ((polars col passenger_count) <= 4) and ((polars col vendor_id) == 2) ) | polars with-column ( polars when ((polars col trip_duration) > 1800) | polars then "long" | polars when ((polars col trip_duration) > 900) | polars then "medium" | polars otherwise "short" | polars as trip_category ) | polars group-by trip_category | polars agg (polars col trip_duration | polars count | polars as trip_count) | polars collect ``` ### Native Nushell Data Analysis ```nushell # Statistical operations without Polars open data.csv | select trip_duration passenger_count vendor_id | where trip_duration > 300 | where passenger_count <= 4 | insert trip_category {|row| if $row.trip_duration > 1800 { "long" } else if $row.trip_duration > 900 { "medium" } else { "short" } } | group-by trip_category | each {|group, trips| { category: $group count: ($trips | length) avg_duration: ($trips.trip_duration | math avg) total_passengers: ($trips.passenger_count | math sum) } } # Histogram generation [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] | group-by --to-table {$in // 5 * 5} # Create bins | each {|row| { bin: $row.items.0 count: ($row.items | length) } } | sort-by bin # Window functions simulation def rolling-average [window: int] { let data = $in 0..($data | length | $in - $window + 1) | each {|i| $data | skip $i | first $window | math avg } } # Usage [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] | rolling-average 3 # => [2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0] ``` --- ## Module System ### Module Definition @@ -1181,6 +1458,15 @@ if, match, for, while, try, catch, break, continue # Functions def, return, help, which, source, use # Database operations stor open, stor create, stor insert, query db, stor export # JSON processing from json, to json, get, select, where, group-by # Data analysis polars open, polars collect, polars group-by, polars agg, math sum, math avg ``` ### Keyboard Shortcuts -
danielbodnar created this gist
Sep 20, 2025 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,1212 @@ # Nushell v0.107.0+ Comprehensive Cheatsheet > A comprehensive reference for modern Nushell development following Unix Philosophy and Daniel Bodnar's coding standards. ## Table of Contents - [Basic Syntax](#basic-syntax) - [Data Types](#data-types) - [Variables and Scope](#variables-and-scope) - [Functions and Commands](#functions-and-commands) - [Pipeline Operations](#pipeline-operations) - [Control Flow](#control-flow) - [File Operations](#file-operations) - [String Operations](#string-operations) - [Data Manipulation](#data-manipulation) - [Module System](#module-system) - [Error Handling](#error-handling) - [Configuration](#configuration) - [Advanced Patterns](#advanced-patterns) - [Unix Integration](#unix-integration) - [Best Practices](#best-practices) --- ## Basic Syntax ### Comments and Documentation ```nushell # Single line comment # Multi-line documentation # This is a comprehensive function # that follows Unix Philosophy def my-function [] { # Implementation } ``` ### Help System ```nushell help # General help help commands # List all commands help <command> # Specific command help <command> --help # Command-specific help ``` ### Basic Operations ```nushell # Arithmetic 1 + 2 # Addition 10 - 5 # Subtraction 3 * 4 # Multiplication 15 / 3 # Division 2 ** 3 # Exponentiation 17 mod 5 # Modulo # Comparison 5 == 5 # Equal 5 != 3 # Not equal 5 > 3 # Greater than 5 < 10 # Less than 5 >= 5 # Greater than or equal 5 <= 10 # Less than or equal # Logical true and false # Logical AND true or false # Logical OR not true # Logical NOT ``` --- ## Data Types ### Primitive Types ```nushell # Numbers 42 # Integer 3.14 # Float 0x2A # Hexadecimal 0o52 # Octal 0b101010 # Binary # Strings "hello world" # Double quoted 'single quoted' # Single quoted `raw string` # Raw string (no escaping) # Booleans true false # Nothing/Null null nothing # Duration 1day # 1 day 2hr # 2 hours 30min # 30 minutes 45sec # 45 seconds ``` ### Structured Types ```nushell # Lists [1, 2, 3, 4] # Simple list ["a", "b", "c"] # String list [1, "mixed", true] # Mixed types # Records { # Multi-line record name: "John" age: 30 active: true } {name: "Jane", age: 25} # Single-line record # Tables [ # List of records {name: "Alice", age: 30} {name: "Bob", age: 25} ] ``` ### Type Checking ```nushell "hello" | describe # Get type information 42 | describe # "int" [1, 2, 3] | describe # "list<int>" # Type predicates $value | is-empty # Check if empty $value | is-not-empty # Check if not empty ``` --- ## Variables and Scope ### Variable Declaration ```nushell # Immutable variables let name = "John" let age = 30 let items = [1, 2, 3] # Mutable variables mut counter = 0 $counter = $counter + 1 # Constants const PI = 3.14159 const APP_VERSION = "1.0.0" # Environment variables $env.PATH # Access environment variable $env.MY_VAR = "value" # Set environment variable ``` ### Scope and Shadowing ```nushell let x = 10 do { let x = 20 # Shadows outer x $x # Returns 20 } $x # Still 10 ``` ### Destructuring ```nushell # List destructuring let [first, second, ..rest] = [1, 2, 3, 4, 5] # Record destructuring let {name, age} = {name: "John", age: 30} # Nested destructuring let {user: {name, email}} = { user: {name: "John", email: "[email protected]"} } ``` --- ## Functions and Commands ### Function Definition ```nushell # Basic function def greet [name: string] { $"Hello, ($name)!" } # Function with multiple parameters def calculate [ x: int # Required parameter y: int # Required parameter operation: string = "add" # Optional with default ] { match $operation { "add" => $x + $y "subtract" => $x - $y "multiply" => $x * $y "divide" => $x / $y _ => (error make {msg: "Invalid operation"}) } } # Function with flags def process-data [ data: any --verbose (-v) # Boolean flag --format: string = "json" # String flag with default --output: path # Path flag ] { if $verbose { print "Processing data..." } # Implementation $data } ``` ### Input/Output Signatures ```nushell # Input from pipeline def process-list []: list<any> -> list<any> { $in | each {|item| $item * 2} } # Multiple input types def format-value []: [string, int, float] -> string { $in | into string } # Table input/output def filter-adults []: table -> table { $in | where age >= 18 } ``` ### Advanced Function Features ```nushell # Rest parameters def sum [...numbers: int] { $numbers | math sum } # Optional parameters def greet [name?: string] { let name = $name | default "World" $"Hello, ($name)!" } # Type unions def process [value: int | string] { match ($value | describe) { "int" => $value * 2 "string" => $value + " processed" _ => $value } } ``` ### Custom Commands ```nushell # Environment command def --env load-config [] { let config = open config.json $env.DATABASE_URL = $config.database.url } # Wrapped command def --wrapped git-log [ ...args: string ] { ^git log ...$args --oneline --graph } ``` --- ## Pipeline Operations ### Basic Piping ```nushell # Simple pipeline ls | where size > 1KB | sort-by name # Multiple transformations open data.json | select name age | where age > 25 | sort-by age | reverse ``` ### Pipeline Operators ```nushell # Standard pipe $data | filter {|x| $x > 10} # Assignment pipe $data |= each {|x| $x * 2} # Error propagation $data | try-each {|x| $x / 0} | default 0 ``` ### Advanced Pipeline Patterns ```nushell # Branching pipeline $data | tee {|x| $x | save backup.json} | where active == true | select name email # Parallel processing $large_list | par-each {|item| # CPU-intensive operation heavy-computation $item } # Pipeline with side effects $data | each {|row| print $"Processing ($row.name)..." process-row $row } ``` --- ## Control Flow ### Conditionals ```nushell # Simple if if $age >= 18 { "adult" } else { "minor" } # Multi-condition if $score >= 90 { "A" } else if $score >= 80 { "B" } else if $score >= 70 { "C" } else { "F" } # Conditional assignment let status = if $active { "running" } else { "stopped" } ``` ### Pattern Matching ```nushell # Basic match match $value { 1 => "one" 2 => "two" 3 => "three" _ => "other" } # Type-based matching match ($input | describe) { "int" => $input * 2 "string" => $input + " suffix" "list" => ($input | length) _ => null } # Guard patterns match $number { x if $x > 100 => "large" x if $x > 50 => "medium" x if $x > 0 => "small" _ => "zero or negative" } ``` ### Loops ```nushell # For loop for item in $list { print $item } # While loop mut i = 0 while $i < 10 { print $i $i = $i + 1 } # Loop with break/continue for item in $items { if $item == "skip" { continue } if $item == "stop" { break } print $item } ``` --- ## File Operations ### File System Navigation ```nushell # Directory operations ls # List current directory ls -la # Detailed listing ls **/*.nu # Recursive glob pattern cd /path/to/directory # Change directory pwd # Print working directory # Path operations "path/to/file.txt" | path dirname # Get directory "path/to/file.txt" | path basename # Get filename "path/to/file.txt" | path extension # Get extension "path/to" | path join "file.txt" # Join paths ``` ### File I/O ```nushell # Reading files open file.txt # Open and read file open data.json # Parse JSON open data.csv # Parse CSV open config.toml # Parse TOML open image.png # Read binary data # Writing files "content" | save file.txt # Save string $data | to json | save data.json # Save as JSON $table | to csv | save data.csv # Save as CSV # Append to files "new line" | save --append log.txt ``` ### File Manipulation ```nushell # Copy/move/delete cp source.txt dest.txt # Copy file mv old.txt new.txt # Move/rename rm file.txt # Delete file rm -rf directory/ # Delete directory recursively # File information stat file.txt # File metadata file file.txt # File type which command # Find command location ``` ### Directory Operations ```nushell # Create/remove directories mkdir new_directory mkdir -p path/to/nested/directory rmdir empty_directory # Directory traversal find . -name "*.nu" # Find files by pattern find . -type f -size +1KB # Find by size glob **/*.{nu,md} # Glob patterns ``` --- ## String Operations ### Basic String Operations ```nushell # String interpolation let name = "World" $"Hello, ($name)!" # String interpolation # String methods "hello world" | str length # Length "hello world" | str upcase # Uppercase "hello world" | str downcase # Lowercase "hello world" | str capitalize # Capitalize " hello " | str trim # Trim whitespace ``` ### String Manipulation ```nushell # Splitting and joining "a,b,c" | split row "," # Split string ["a", "b", "c"] | str join "," # Join list # Replacement "hello world" | str replace "world" "universe" "hello world" | str replace -a "l" "L" # Replace all # Substring operations "hello world" | str substring 0..5 # Substring "hello world" | str starts-with "hello" # Starts with "hello world" | str ends-with "world" # Ends with "hello world" | str contains "wor" # Contains ``` ### Pattern Matching ```nushell # Regular expressions "hello123world" | str replace -r '\d+' "_" # Regex replace "[email protected]" | parse -r '(?P<user>.+)@(?P<domain>.+)' # Parsing patterns "name: John, age: 30" | parse "name: {name}, age: {age}" ``` --- ## Data Manipulation ### Working with Lists ```nushell # List operations [1, 2, 3] | length # Get length [1, 2, 3] | first # First element [1, 2, 3] | last # Last element [1, 2, 3] | get 1 # Get by index [1, 2, 3, 4] | slice 1..3 # Slice # List transformation [1, 2, 3] | each {|x| $x * 2} # Map [1, 2, 3, 4] | filter {|x| $x > 2} # Filter [1, 2, 3] | reduce {|acc, x| $acc + $x} # Reduce # List manipulation [1, 2] | append 3 # Add to end [2, 3] | prepend 1 # Add to beginning [1, 2, 3, 2] | uniq # Remove duplicates [3, 1, 2] | sort # Sort [1, 2, 3] | reverse # Reverse ``` ### Working with Records ```nushell # Record operations {name: "John", age: 30} | get name # Get field {name: "John", age: 30} | select name # Select fields {name: "John", age: 30} | reject age # Remove fields # Record transformation {name: "john"} | update name {|x| $x.name | str capitalize} {name: "John"} | insert age 30 # Add field {name: "John", age: 30} | upsert age 31 # Update or insert ``` ### Working with Tables ```nushell # Table operations $table | select name age # Select columns $table | where age > 25 # Filter rows $table | sort-by age # Sort by column $table | group-by department # Group by column # Table aggregation $table | math sum # Sum numeric columns $table | math avg # Average $table | math max # Maximum $table | math min # Minimum # Table joining $table1 | join $table2 id # Join tables $table1 | merge $table2 # Merge tables ``` ### Data Conversion ```nushell # Type conversion "123" | into int # String to int 123 | into string # Int to string "true" | into bool # String to bool "2023-01-01" | into datetime # String to datetime # Format conversion $data | to json # Convert to JSON $data | to csv # Convert to CSV $data | to toml # Convert to TOML $data | to yaml # Convert to YAML # From formats '{"name": "John"}' | from json # Parse JSON "name,age\nJohn,30" | from csv # Parse CSV ``` --- ## Module System ### Module Definition ```nushell # Basic module export module utils { # Export functions export def greet [name: string] { $"Hello, ($name)!" } # Private function (not exported) def internal-helper [] { "internal use only" } # Export constants export const VERSION = "1.0.0" } ``` ### Advanced Module Features ```nushell # Module with submodules export module data { export module parsers { export def parse-json [input: string] { $input | from json } export def parse-csv [input: string] { $input | from csv } } export module validators { export def validate-email [email: string] { $email | str match -r '^[^@]+@[^@]+\.[^@]+$' } } } ``` ### Module Usage ```nushell # Import entire module use utils # Import specific items use utils [greet, VERSION] # Import with alias use utils as u # Import from submodule use data parsers use data parsers [parse-json] # Conditional imports if $env.DEVELOPMENT? { use dev-tools } ``` ### Overlays and Environments ```nushell # Create overlay overlay use my-tools # Environment overlay overlay use --env my-env-config # Remove overlay overlay hide my-tools # List overlays overlay list ``` --- ## Error Handling ### Basic Error Handling ```nushell # Try-catch pattern try { let result = risky-operation $result } catch {|error| print $"Error occurred: ($error.msg)" null } # Default values risky-operation | default "fallback value" # Error propagation def safe-divide [a: int, b: int] { if $b == 0 { error make {msg: "Division by zero"} } else { $a / $b } } ``` ### Advanced Error Handling ```nushell # Custom error types error make { msg: "Custom error message" label: { text: "This is the problematic part" start: 10 end: 15 } help: "Try using a different value" } # Error context def process-file [filename: path] { try { open $filename } catch {|err| error make { msg: $"Failed to process file: ($filename)" help: $"Original error: ($err.msg)" } } } # Graceful degradation def robust-operation [] { let primary = try { primary-method } catch { null } let fallback = try { fallback-method } catch { null } $primary | default $fallback | default "last resort" } ``` --- ## Configuration ### Configuration Files ```nushell # Config location $nu.config-path # Main config file $nu.env-path # Environment config # Load custom config source ~/.config/nushell/custom.nu # Conditional config loading if ($env.NUSHELL_PROFILE? | default "default") == "development" { source ~/.config/nushell/dev.nu } ``` ### Environment Configuration ```nushell # Set environment variables $env.EDITOR = "nvim" $env.BROWSER = "firefox" $env.PATH = ($env.PATH | split row (char esep) | append "/opt/local/bin") # Custom prompt $env.PROMPT_COMMAND = {|| let user = $env.USER? | default "unknown" let pwd = (pwd | str replace $env.HOME "~") $"($user)@(hostname):($pwd)> " } # Custom completions $env.config = { completions: { case_sensitive: false quick: true partial: true algorithm: "prefix" } } ``` ### Aliases and Shortcuts ```nushell # Simple aliases alias ll = ls -la alias grep = rg alias cat = bat # Function-based aliases def gst [] { git status } def gco [...branches] { git checkout ...$branches } # Conditional aliases if (which code | is-not-empty) { alias edit = code } else { alias edit = nvim } ``` --- ## Advanced Patterns ### Functional Programming Patterns ```nushell # Higher-order functions def apply-twice [func: closure, value: any] { do $func $value | do $func } # Currying simulation def multiply [x: int] { {|y| $x * $y} } let double = multiply 2 [1, 2, 3] | each $double # Function composition def compose [f: closure, g: closure] { {|x| do $g (do $f $x)} } ``` ### Metaprogramming ```nushell # Dynamic function creation def create-getter [field: string] { {|record| $record | get $field} } let get-name = create-getter "name" {name: "John", age: 30} | do $get-name # Code generation def generate-validator [rules: record] { let checks = $rules | items {|key, value| $"if not \($input | get ($key)\) ($value.operator) ($value.threshold) { return false }" } | str join "\n" $"def validate [input: record] {\n($checks)\n true\n}" } ``` ### Performance Patterns ```nushell # Lazy evaluation def lazy-range [start: int, end: int] { {|take| mut current = $start mut count = 0 while $current < $end and $count < $take { yield $current $current = $current + 1 $count = $count + 1 } } } # Streaming data processing def process-large-file [filename: path] { open $filename | lines | each {|line| # Process line-by-line to avoid memory issues process-line $line } | collect {|chunk| save-chunk $chunk} } # Parallel processing def parallel-map [func: closure, data: list] { $data | par-each {|item| do $func $item} } ``` --- ## Unix Integration ### Process Management ```nushell # Running external commands ^ls -la # Run external command ^git status | lines | first 10 # Pipe external output # Process information ps | where name =~ "nushell" # List processes kill 1234 # Kill process by PID # Background processes ^long-running-command & # Run in background jobs # List background jobs ``` ### Shell Integration ```nushell # Command substitution equivalent let files = (^find . -name "*.nu" | lines) let branch = (^git branch --show-current | str trim) # Shell scripting patterns #!/usr/bin/env nu def main [action: string, ...args] { match $action { "start" => start-service ...$args "stop" => stop-service ...$args "status" => show-status ...$args _ => { print "Usage: script.nu <start|stop|status> [args...]" exit 1 } } } ``` ### System Administration ```nushell # File permissions ^chmod +x script.nu ^chown user:group file.txt # System monitoring def system-info [] { { uptime: (^uptime | str trim) memory: (^free -h | from ssv) disk: (^df -h | from ssv) load: (^cat /proc/loadavg | str trim) } } # Log analysis def analyze-logs [logfile: path] { open $logfile | lines | where ($it | str contains "ERROR") | parse "{timestamp} {level} {message}" | group-by level | sort-by timestamp } ``` --- ## Best Practices ### Code Organization ```nushell # Module structure export module project { # Constants at the top export const VERSION = "1.0.0" export const DEFAULT_CONFIG = "config.toml" # Type definitions export def user-record [] { {name: string, age: int, email: string} } # Public API functions export def create-user [name: string, age: int, email: string] { # Validation validate-user-input $name $age $email # Create record { name: $name age: $age email: $email created: (date now) } } # Private helper functions def validate-user-input [name: string, age: int, email: string] { if ($name | str length) == 0 { error make {msg: "Name cannot be empty"} } if $age < 0 { error make {msg: "Age must be positive"} } if not ($email | str contains "@") { error make {msg: "Invalid email format"} } } } ``` ### Documentation Patterns ```nushell # Comprehensive function documentation # Process user data with validation and transformation # # This function takes raw user input, validates it according to business rules, # transforms it into the standard format, and returns a structured record. # # Parameters: # input: Raw user data (any format) # strict: Enable strict validation mode # # Returns: # Validated and normalized user record # # Errors: # - ValidationError: Input data doesn't meet requirements # - TransformError: Unable to transform data to required format # # Examples: # process-user {name: "John", age: "30"} # process-user $raw_data --strict def process-user [ input: any # Raw user data to process --strict # Enable strict validation mode ]: any -> record { # Implementation with comprehensive error handling try { validate-input $input $strict transform-data $input } catch {|error| error make { msg: $"Failed to process user: ($error.msg)" help: "Check input format and try again" } } } ``` ### Testing Patterns ```nushell # Test function pattern def test-user-creation [] { # Test setup let test-user = {name: "John", age: 30, email: "[email protected]"} # Test execution let result = create-user $test-user.name $test-user.age $test-user.email # Assertions assert ($result.name == $test-user.name) assert ($result.age == $test-user.age) assert ($result.email == $test-user.email) assert ($result.created != null) print "✅ User creation test passed" } # Test runner def run-tests [] { let test-functions = [ test-user-creation test-user-validation test-data-transformation ] let results = $test-functions | each {|test| try { do $test {name: ($test | str replace "test-" ""), status: "PASS"} } catch {|error| {name: ($test | str replace "test-" ""), status: "FAIL", error: $error.msg} } } let passed = ($results | where status == "PASS" | length) let total = ($results | length) print $"Tests: ($passed)/($total) passed" $results | where status == "FAIL" | each {|test| print $"❌ ($test.name): ($test.error)" } } ``` ### Performance Best Practices ```nushell # Efficient data processing def process-large-dataset [data: list] { $data | par-each {|chunk| # Parallel processing $chunk | filter {|item| $item.active} # Early filtering | select name value # Select only needed fields | update value {|row| calculate-value $row.value} # Transform } | flatten # Combine results | sort-by name # Final sorting } # Memory-efficient file processing def process-log-file [filename: path] { open $filename | lines # Stream lines | par-each {|line| # Parallel line processing if ($line | str starts-with "ERROR") { parse-error-line $line } else { null } } | compact # Remove nulls | collect {|errors| # Batch results save-errors $errors } } ``` ### Unix Philosophy Implementation ```nushell # Rule of Modularity: Simple parts, clean interfaces def data-processor [] { # Single responsibility: process data $in | validate-data | transform-data | format-output } # Rule of Composition: Design for connection def csv-to-json []: string -> string { $in | from csv | to json } # Rule of Silence: Say nothing when nothing to say def quiet-operation [] { try { risky-operation } catch { # Fail silently, let caller handle null } } # Rule of Repair: Fail noisily and fast def validate-config [config: record] { if "database" not-in $config { error make {msg: "Missing required 'database' configuration"} } if "host" not-in $config.database { error make {msg: "Missing required 'database.host' configuration"} } # More validations... } ``` --- ## Quick Reference ### Essential Commands ```nushell # File operations ls, cd, pwd, cp, mv, rm, mkdir, find, glob # Data manipulation select, where, sort-by, group-by, each, filter, reduce # String operations str length, str replace, str trim, str split, str join # Type conversion into int, into string, to json, from csv, describe # Pipeline |, each, filter, map, reduce, collect, par-each # Control flow if, match, for, while, try, catch, break, continue # Functions def, return, help, which, source, use ``` ### Keyboard Shortcuts ```nushell Ctrl+C # Interrupt current command Ctrl+D # Exit shell Ctrl+L # Clear screen Ctrl+R # Reverse search history Tab # Auto-completion Shift+Tab # Reverse completion Up/Down # Command history Ctrl+A # Move to beginning of line Ctrl+E # Move to end of line ``` ### Environment Variables ```nushell $env.PATH # System PATH $env.HOME # Home directory $env.PWD # Current directory $env.USER # Current user $nu.config-path # Nushell config file $nu.env-path # Nushell environment file $nu.home-path # Nushell home directory ``` --- *This cheatsheet covers Nushell v0.107.0+ features following Unix Philosophy principles and modern development practices. For the latest updates, refer to the [official Nushell documentation](https://nushell.sh).*