Filters to select subsets of data
Nushell has a small set of filters for taking part of a list or table: some select rows by position, some select columns by name, and cell paths reach into nested data. To select rows by a condition instead of a position, see where.
See also: Navigating and Accessing Structured Data and Working with Tables in the Book, and get vs. select.
The examples below use this table:
let t = [
[name lang stars];
[nushell rust 38000]
[reedline rust 700]
[nu_scripts nushell 3000]
[vscode-ext typescript 200]
]Rows by Position
| Command | Keeps |
|---|---|
first n, last n | The first or last n rows (without n: a single item, not a list) |
take n, skip n | The first n rows, or everything after them |
drop n | Everything except the last n rows |
slice range | The rows whose index is in the range |
select 0 2 ... | The rows with the given indices |
drop nth 0 2 ... | Every row except the given indices |
take while, skip while, take until, skip until | Rows up to, or from, the first row where a condition changes |
$t | first 2
# => ╭───┬──────────┬──────┬───────╮
# => │ # │ name │ lang │ stars │
# => ├───┼──────────┼──────┼───────┤
# => │ 0 │ nushell │ rust │ 38000 │
# => │ 1 │ reedline │ rust │ 700 │
# => ╰───┴──────────┴──────┴───────╯Ranges in slice include their end. Use ..< to exclude it, and a negative start to count from the end:
[a b c d e] | slice 1..3
# => ╭───┬───╮
# => │ 0 │ b │
# => │ 1 │ c │
# => │ 2 │ d │
# => ╰───┴───╯[a b c d e] | slice (-2)..
# => ╭───┬───╮
# => │ 0 │ d │
# => │ 1 │ e │
# => ╰───┴───╯first and last without a count return nothing for empty input. Add --strict to make that an error instead.
Columns by Name
selectkeeps the named columns and returns a table (or a record for record input).rejectremoves the named columns and keeps the rest.getreturns the values: a list for a table column, a plain value for a record field.
$t | select name stars | first 2
# => ╭───┬──────────┬───────╮
# => │ # │ name │ stars │
# => ├───┼──────────┼───────┤
# => │ 0 │ nushell │ 38000 │
# => │ 1 │ reedline │ 700 │
# => ╰───┴──────────┴───────╯$t | get name
# => ╭───┬────────────╮
# => │ 0 │ nushell │
# => │ 1 │ reedline │
# => │ 2 │ nu_scripts │
# => │ 3 │ vscode-ext │
# => ╰───┴────────────╯To pass column names from a list, spread it with .... Passing the list itself is a type error:
let cols = [name stars]
$t | select ...$cols | first 1
# => ╭───┬─────────┬───────╮
# => │ # │ name │ stars │
# => ├───┼─────────┼───────┤
# => │ 0 │ nushell │ 38000 │
# => ╰───┴─────────┴───────╯Cell Paths
A cell path is a dotted list of column names and row indices. It can follow a variable directly ($t.0.name), or be given to get, select, reject, update, sort-by and many other commands. Row and column members can come in either order:
[$t.0.name $t.name.0 ($t | get 1.name)]
# => ╭───┬──────────╮
# => │ 0 │ nushell │
# => │ 1 │ nushell │
# => │ 2 │ reedline │
# => ╰───┴──────────╯With select, a nested cell path becomes a column named after the whole path:
{a: {b: {c: 1}}} | select a.b.c
# => ╭───────┬───╮
# => │ a.b.c │ 1 │
# => ╰───────┴───╯Members that contain spaces or dots are quoted: $record."first name". A cell path can also be stored in a variable with the $. literal syntax, e.g. let p = $.a.b; $data | get $p.
Missing Data and Case
A missing column or row is an error. Add ? after a member (or pass --optional/-o to get, select or reject) to get null instead:
{name: nu} | get version
# => Error: nu::shell::column_not_found
# =>
# => × Cannot find column 'version'
# => ╭─[repl_entry #1:1:1]
# => 1 │ {name: nu} | get version
# => · ─────┬──── ───┬───
# => · │ ╰── column 'version' is missing in one or more values
# => · ╰── value originates here
# => ╰────
# => help: If some rows have this column, try using 'version?' for optional access, or pre-fill using the `default` command{name: nu} | get version? | describe
# => nothingColumn names are matched case-sensitively. Add ! after a member (or pass --ignore-case to get, select or reject) to match case-insensitively:
{Name: nu} | get name!
# => nu