Nushell
Updated: 08 October 2024
About
Nushell makes use of command outputs as data that can be transformed, it makes use of pipes that connnect commands together in a functional-programming usage style
Thinking in Nu
Nushell works with results using pipes, this is similar to >
in bash but isn’t exactly the same
Immutability
Variables are immutable, however values can be shadowed, so I can create a shadowing x
based on a previous x
like so:
Scoping
Nushell uses scoped environmments in blocks, so a command can use a value within its scope like so:
Fundamentals
Types of Data
The describe
command returns the type of a variable
Conversions
The into
command can convert variable types
Strings
Strings can be created as:
- Double quotes:
"hello world"
- Single quotes:
'hello: "world"'
- Interpolated:
$"my number = (40 + 2)"
- Bare:
hello
Bools
Booleans are simply true
and false
Dates
Dates can be in the following formats:
2022-02-02
2022-02-02T14:30:00
2022-02-02T14:30:00+05:00
Durations
Nushell has the following durations:
ns
nanosecondus
microsecondms
millisecondsec
secondmin
minutehr
hourday
daywk
week
And can be used like so:
Or in calculations
Ranges
Ranges can be done as 1..3
for example, by default the end is inclusive, ranges can also be open ended ..2
or 2..
Records
Records hold key-value pairs, and may or may not have commas between entry names:
A record is the same as a single row of a table
Records can be iterated over by transposing them into a table:
And accessing properties can be done like:
Or
Lists
Lists are ordered sequences of data and use []
with optional ,
separators. The below will create alist of strings
A list is the same as a single column table
Indexing lists can be done with a .
as with records:
Or using ranges:
Tables
Tables can be created with the following syntax:
Tables can also be created from json
Internally tables are just a list of records
Blocks
Blocks of code are denoted using {}
, for example:
Loading Data
Open Files
Files can be opened with the open
command:
Nu will parse the file if it can and will return data and not just a plain string
If a file extension isn’t what the type usually has, we can still parse the file, we just ned to tell nu that it’s a specific format, so we can do this like so:
Manipulating Strings
String data can be manipulated using things like the lines
command which will split each line into a row:
And we can further apply the split
command on the column to split it by some specific character:
Additionally, we can use trim
:
And lastly, we can transform it into a table with formal column names with some additional properties on the split
command:
Fetch Urls
We can also fetch remote files which will then also be converted into data like so:
Cheatsheet
Moving around the File System
Nushell provides commands for normal file-system related tasks which are similar to common commands such as:
Listing Files
Or listing a specific file type
Or even globs
Globs
You can also use the glob
method directly to find files recursively:
The
glob
method returns a list of strings versus thels
method which returns a list of file objects
Stopping All Docker Containers
The Docker CLI outputs data that’s nicely structured for working with the NuShell table structure.
We can kill all containers by parsing the data into a table and stopping them individually
Config
Some utils from my current config.nu
, primarily for working with Git
Notifiy
A little script that’s also useful to have is this one that will notify you when a task completes. It’s a handy way to be notified when a long running task completes
This uses AppleScript as per the example on stackexchange so it will only work on MacOS. I’m sure there’s a similar way to accomplish this on other operating systems
You can include the above in your nushell config and use it as follows:
It will also handle printing the output from the task being run
The $in
Param and Closures
Nushell functions can also use an implicit input parameter, this can be used when defining a function, for example:
Which can then be used as
Additionally, note that example "Hello World!"
will not work since $in
params cannot be passed positionally and can only be used part of a pipeline
It’s also possible to use $in
when we epect a closure which lets us leave out the parameter definition, for example, we can run ls
in all subdirectories of an input like so:
The { ls $in.name }
is the same as a closure like {|f| ls $f.name }
so it’s a bit easier to type in this scenario as well.
Parsing
The parse
function can be used to read some string into a usable data structure, take the following file for example:
The parse command lets us structure that using:
Input
You can take in user input using the input
function, this allows for dynamic imput. This is handy for doing a search over some list, for example composing it with the above:
Closures
Nushell does something quite interesting with closures. Since everything is immutable it’s possible to do environment-changing operations in a somewhat contained way.
For example, I can do
some stuff like moving to a different folder, but I will not be affected outside of the closure
Or I can cd
into each folder and ls
each of them, while remaining in my parent folder.
Parallel
Due to the isolation that closures afford us, we can also run these in parallel, nushell has parallel methods of some commands, e.g. the each
command, which can be used with par-each
:
This works the same but is much faster for large/complex tasks
Timer
Nushell also has a timeit
command that can be used to time the execution of any block, for example: