Nushell Cookbook

The purpose of this page is to collect common Nushell scripts and examples. The goal is to make it easier to understand Nushell and find common usage examples.

Common list (ls) examples:

ls | sort-by size | reverse
ls | where size > 1kb
sys | get host.sessions.name

Installation

cargo install --locked nu

Configuration

Good References

Strings

'hello world'

Records vs Tables vs Lists

List: an ordered collection of values. Accessed by index.

Record: key/value list - Lists that can hold more than one value. These can be simple values. They can also hold rows, and the combination of a list of records is often called a "table".

Table: core data structure - comes with existing commands (sort, sort-by, etc...)

Lists

[1, 2, 3, 4] | insert 2 10
[1, 2, 3, 4] | each { |it| $"Hello, ($it)!" } -- iterator
[1, 2, 3, 4] | each -n { |it| $"($it.index + 1) - ($it.item)" } -- numbered iterator

Nushell Scripts and Commands

Here is an example of a command:

# A greeting command that can greet the caller
def greet [
   name: string = "some default"  # name of the person
   --age (-a): int                # age of the person
   --twice                        # flag to print again
 ] {
   if $twice {
     [$name $name $age $age]
   } else {
     [$name $age]
   }
 }

Where:

Native OS Commands

To make a call to a non-nushell command, there is nothing special you need to do. Here is an example where you can use nushell with commands installed on the OS like psql. In this example we ask psql to return the results of the query in json ("-AXqtc").

psql -h localhost -d idempiere -U adempiere -AXqtc "SELECT JSON_AGG(t) FROM (select * from c_order) t" | from json

We use the nushell "from json" at the end to show the results in a nushell table.

String Concatenation

Working with Strings in Nushell

Here is an example to compose a sql string and use it in psql:

let sql = open some.sql
echo $sql
let jsql = ["SELECT JSON_AGG(t) FROM (",$sql,") t"] | str join
echo $jsql
psql -h localhost -d idempiere -U adempiere -AXqtc $jsql | from json

An alternative to "str join" is to use string interpolation.

psql -h localhost -d idempiere -U adempiere -AXqtc $"SELECT JSON_AGG\(t) FROM \((open some.sql)) t" | from json

Save Table to File

There are times when you want to save results from a command (say psql) to file so that you do not need to run the command again. Note the nuon standard is a superset of json.

psql -h localhost -d idempiere -U adempiere -AXqtc "SELECT JSON_AGG(t) FROM (select * from c_order) t" | from json | save results.nuon

If you want to open results.nuon:

open results.nuon

If you want to see all columns in one screen:

open results.nuon | transpose

Note that you can also save directly to a json file:

psql -h localhost -d idempiere -U adempiere -AXqtc "SELECT JSON_AGG(t) FROM (select * from c_order) t" | save results.json

open results.json

Working with toml Files

Let's assume you are string journal entries in toml. Here is an example file:

[[entries]]
date_time = 2023-05-25T09:30:00Z
title = "My First Journal Entry"
body = "Today was a great day. I started my journal!"
starred = true
tags = ["personal", "journal"]

[[entries]]
date_time = 2023-05-26T14:45:00Z
body = "I had a productive meeting at work."
starred = false
tags = ["work"]

Here are some example commands you can run against this file.

Find all starred entries:

open some.toml | get entries | where starred == true

Find all starred entries when the starred object might be missing (note the ? for 'starred'):

open some.toml | get entries | where starred? == true

Here is how you further iterate across the records for more advanced filtering:

open some.toml | get entries | where { |entry| ($entry | is-not-empty starred) and ($entry.starred? == true) }

To check if the object/property exists, you can use 'key' in $record.

Find all tags:

open some.toml | get entries | get tags | flatten

Find unique/distinct tags:

open some.toml | get entries | get tags | flatten | uniq

Find all entries where any of the tags are used:

open some.toml | get entries | where { get tags | any {|tag| $tag in [personal journal]}}

Combining both tag search and starred by simply appending another pipe and where:

open some.toml | get entries | where { get tags | any {|tag| $tag in [personal journal]}} | where starred? == true

Look for an record with no starred column (missing from record):

open some.toml | get entries | where { get tags | any {|tag| $tag in [personal journal]}} | where starred? == null

HTTP Post to OpenAI

Create embeddings:

let content = (open /tmp/some-test.txt)
let api_key = "sk-proj-..."
let body = {model: "text-embedding-3-large", input: $content} | to json
let response = (http post --headers [Authorization $"Bearer ($api_key)"] --content-type application/json https://api.openai.com/v1/embeddings $body)

References:

cat and pipe to a New Command

Note that you can use $in as the parameter target for a command that does not accept stdin.

cat your_file | rag query $in

AI in Nushell

Manage 3rd Party Libraries

Until unpm is mature enough.. You might want to manage third-party libraries yourself by cloning them to a directory like ~/nu_libs.

git clone --depth=1 https://github.com/fj0r/ai.nu.git ~/nu_libs/ai.nu

Add the following to your env.nu file:

$env.NU_LIB_DIRS ++= glob ~/nu_libs/*

And add the following to your config.nu file:

use ai *

Here is an example all-in-one script:

git clone --depth=1 https://github.com/fj0r/ai.nu.git ~/nu_libs/ai.nu
 if [ -z "${XDG_CONFIG_HOME}" ]; then
     # If not set, set it to the default value (~/.config)
     export XDG_CONFIG_HOME="${HOME}/.config"
 fi
 mkdir -p $XDG_CONFIG_HOME/nushell/
 echo \$env.NU_LIB_DIRS ++= glob ~/nu_libs/* | tee -a $XDG_CONFIG_HOME/nushell/env.nu
 echo use ai * | tee -a $XDG_CONFIG_HOME/nushell/config.nu