Nushell
安装 Nu !
快速开始
  • Nushell 之书
  • 命令参考列表
  • 实战指南
  • 语言参考指南
  • 贡献指南
博客
  • English
  • 中文
  • Deutsch
  • Français
  • Español
  • 日本語
  • Português do Brasil
  • Русский язык
  • 한국어
GitHub
安装 Nu !
快速开始
  • Nushell 之书
  • 命令参考列表
  • 实战指南
  • 语言参考指南
  • 贡献指南
博客
  • English
  • 中文
  • Deutsch
  • Français
  • Español
  • 日本語
  • Português do Brasil
  • Русский язык
  • 한국어
GitHub
  • 语言参考指南
  • 过滤器
    • each 和 par-each
    • 选择数据子集的过滤器
    • where 和 filter
    • 理解 get 和 select 的区别

where 和 filter

where 保留列表或表格中条件为 true 的项或行,丢弃其余部分。条件有两种写法:

  • 行条件:直接写在 where 后面的表达式,例如 size > 1kb;
  • 闭包:接收每个项并返回 bool,可以内联书写,也可以存在变量里。

filter 是闭包形式的老名字。它自 0.105 起已弃用;请改用 where。

另见:《Nushell 之书》中的处理表格和 处理列表,以及 $it。

行条件

在行条件中,运算符左侧的裸词是当前行的一列(它是单元格路径,所以 info.size 也能用), 而 $it 是当前整行或整个列表项:

let files = [
  [name size type];
  [README.md 2kb file]
  [src 0b dir]
  [build.rs 12kb file]
  [notes.txt 300b file]
]
$files | where type == file and size > 1kb
# => ╭───┬───────────┬─────────┬──────╮
# => │ # │   name    │  size   │ type │
# => ├───┼───────────┼─────────┼──────┤
# => │ 0 │ README.md │  2.0 kB │ file │
# => │ 1 │ build.rs  │ 12.0 kB │ file │
# => ╰───┴───────────┴─────────┴──────╯
[1 2 3 4 5] | where $it > 2
# => ╭───┬───╮
# => │ 0 │ 3 │
# => │ 1 │ 4 │
# => │ 2 │ 5 │
# => ╰───┴───╯

可以使用任何运算符,条件之间可以用 and、or 和 not 组合。用 $it 可以写出跨多列的表达式:

[[name]; [alpha] [beta] [gamma]] | where name in [beta gamma]
# => ╭───┬───────╮
# => │ # │ name  │
# => ├───┼───────┤
# => │ 0 │ beta  │
# => │ 1 │ gamma │
# => ╰───┴───────╯
[[a b]; [1 2] [3 4]] | where ($it.a + $it.b) > 4
# => ╭───┬───┬───╮
# => │ # │ a │ b │
# => ├───┼───┼───┤
# => │ 0 │ 3 │ 4 │
# => ╰───┴───┴───╯

and、or、xor 两侧,或 not 之后的裸词同样也是列名,所以一个 bool 列可以单独作为条件使用:

[{name: a, done: true, urgent: true} {name: b, done: false, urgent: true} {name: c, done: false, urgent: false}] | where not done and urgent
# => ╭───┬──────┬───────┬────────╮
# => │ # │ name │ done  │ urgent │
# => ├───┼──────┼───────┼────────┤
# => │ 0 │ b    │ false │ true   │
# => ╰───┴──────┴───────┴────────╯

外层作用域中的变量可以用在两侧:let limit = 2; $list | where $it > $limit。

行条件是语法,不是值。它不能存进变量;要存请用闭包。

闭包

闭包通过参数与 $in 接收到该项:

[1 2 3 4 5] | where {|n| $n mod 2 == 1 }
# => ╭───┬───╮
# => │ 0 │ 1 │
# => │ 1 │ 3 │
# => │ 2 │ 5 │
# => ╰───┴───╯

存在变量里的闭包可以传给 where。这正是 filter 过去所覆盖的用法:

let is_odd = {|n| $n mod 2 == 1 }
[1 2 3 4 5] | where $is_odd
# => ╭───┬───╮
# => │ 0 │ 1 │
# => │ 1 │ 3 │
# => │ 2 │ 5 │
# => ╰───┴───╯

语言说明

  1. where 作用于列表和表格(包括流),而不作用于单个记录:

    {a: 1} | where a == 1
    # => Error: nu::parser::input_type_mismatch
    # =>
    # =>   × Command does not support record<a: int> input.
    # =>    ╭─[repl_entry #1:1:10]
    # =>  1 │ {a: 1} | where a == 1
    # =>    ·          ──┬──
    # =>    ·            ╰── command doesn't support record<a: int> input
    # =>    ╰────
  2. 如果某些行缺少该列,条件会因 column_not_found 而失败。用 ? 把该成员变成可选的, 这样缺失的值会变成 null:

    [{a: 1} {b: 2}] | where a? == 1
    # => ╭───┬───╮
    # => │ # │ a │
    # => ├───┼───┤
    # => │ 0 │ 1 │
    # => ╰───┴───╯
  3. 只有条件恰好为 true 的行才会被保留。

  4. 行条件不限于 where。any、all、 take while、take until、 skip while、skip until 和 chunk-by 也接受行条件,同时也接受闭包:

    [1 2 3 4 1] | take while $it < 3
    # => ╭───┬───╮
    # => │ 0 │ 1 │
    # => │ 1 │ 2 │
    # => ╰───┴───╯
    [9 8 7 6] | enumerate | any item == index * 2
    # => true
  5. filter 仍然可用,但解析器会打印一条弃用警告:

    [1 2 3] | filter {|x| $x > 1}
    # => Warning: nu::parser::deprecated
    # =>
    # =>   ⚠ Command deprecated.
    # =>    ╭─[repl_entry #1:1:11]
    # =>  1 │ [1 2 3] | filter {|x| $x > 1}
    # =>    ·           ─────────┬─────────
    # =>    ·                    ╰── filter was deprecated in 0.105.0 and will be removed in a future release.
    # =>    ╰────
    # =>   help: `where` command can be used instead, as it can now read the predicate closure from a variable
    # =>
    # => ╭───┬───╮
    # => │ 0 │ 2 │
    # => │ 1 │ 3 │
    # => ╰───┴───╯
在GitHub上编辑此页面
Contributors: NotTheDr01ds, Kieron Wilkinson, fdncred, Jianjun Wang, passionworkeer
Prev
选择数据子集的过滤器
Next
理解 get 和 select 的区别