选择数据子集的过滤器
Nushell 有一小组用于取列表或表格一部分的过滤器:有的按位置选择行,有的按名称选择列, 单元格路径则可以深入到嵌套数据中。如果要按条件而不是按位置选择行,请参见 where。
另见:《Nushell 之书》中的浏览与访问结构化数据和 处理表格,以及 get 与 select 的对比。
下面的示例使用这张表格:
let t = [
[name lang stars];
[nushell rust 38000]
[reedline rust 700]
[nu_scripts nushell 3000]
[vscode-ext typescript 200]
]按位置选择行
| 命令 | 保留的内容 |
|---|---|
first n、last n | 前 n 行或后 n 行(不写数量时是单个项,不是列表) |
take n、skip n | 前 n 行,或它们之后的所有行 |
drop n | 除最后 n 行以外的所有行 |
slice range | 索引落在该区间内的行 |
select 0 2 ... | 具有给定索引的行 |
drop nth 0 2 ... | 除给定索引以外的每一行 |
take while、skip while、take until、skip until | 条件发生变化的那一行之前,或从它开始的各行 |
$t | first 2
# => ╭───┬──────────┬──────┬───────╮
# => │ # │ name │ lang │ stars │
# => ├───┼──────────┼──────┼───────┤
# => │ 0 │ nushell │ rust │ 38000 │
# => │ 1 │ reedline │ rust │ 700 │
# => ╰───┴──────────┴──────┴───────╯slice 中的区间包含其末端。用 ..< 可以排除末端,用负数起点可以从末尾开始计数:
[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 和 last 对空输入返回 nothing。加上 --strict 可以改为报错。
按名称选择列
$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 │
# => ╰───┴────────────╯要从列表传入列名,请用 ... 展开它。直接传入列表本身会导致类型错误:
let cols = [name stars]
$t | select ...$cols | first 1
# => ╭───┬─────────┬───────╮
# => │ # │ name │ stars │
# => ├───┼─────────┼───────┤
# => │ 0 │ nushell │ 38000 │
# => ╰───┴─────────┴───────╯单元格路径
单元格路径是列名与行索引组成的点分列表。它可以直接跟在变量后面($t.0.name), 也可以传给 get、select、reject、update、sort-by 等许多命令。行成员与列成员的顺序可以任意:
[$t.0.name $t.name.0 ($t | get 1.name)]
# => ╭───┬──────────╮
# => │ 0 │ nushell │
# => │ 1 │ nushell │
# => │ 2 │ reedline │
# => ╰───┴──────────╯配合 select 使用时,嵌套的单元格路径会变成一列,并以整个路径命名:
{a: {b: {c: 1}}} | select a.b.c
# => ╭───────┬───╮
# => │ a.b.c │ 1 │
# => ╰───────┴───╯含有空格或点的成员需要加引号:$record."first name"。单元格路径也可以用 $. 字面量语法存进变量, 例如 let p = $.a.b; $data | get $p。
缺失数据与大小写
缺失的列或行会报错。在成员后加上 ?(或给 get、select、reject 传入 --optional/-o) 可以改为得到 null:
{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
# => nothing列名的匹配是区分大小写的。在成员后加上 !(或给 get、select、reject 传入 --ignore-case) 可以不区分大小写地匹配:
{Name: nu} | get name!
# => nu