nushell

出自 ArchWiki

nushell 是一种新型的 shell。它原生支持结构化和类型化数据,例如数组、表格、记录、数值/布尔类型等,并提供语法和内置命令,可以轻松地在类似 shell 的工作流程中查询、过滤、排序、转换、转换和以其他方式操作各种数据类型,并支持以多种内置或用户定义的格式接收输入和生成输出。

安装

Install the nushell 软件包。然后你可以通过运行以下命令启动 nushell

$ nu

功能概述

结构化数据支持

nushell 中的内置命令理解并输出复杂的数据类型。例如,ls 内置命令输出表示文件的项目数组,这些项目具有诸如 namesizetype (filedirsymlink 等)、modified 等属性。

此外,还提供了许多内置命令,用于查询和操作数据,作为数据 - 而不是像传统 shell 那样的文本,同时仍然具有类似 shell 的工作流程。例如,where 内置命令可以过滤数组或表格的内容

$ ls | where type == file | where size > 10mb

由于它通过其“stdin”接收数据并通过其“stdout”生成数据,因此可以像上面那样链接多个过滤器。另一个例子

$ ls | where type == file | get size | sum

get 内置命令可用于访问对象的属性。在此示例中,我们通过 stdin 向其馈送对象数组,因此它会获取数组中每个元素的 size 属性,从而生成数值数组。最后,我们将该数组馈送到 sum,后者计算它们的总和。

输出

nushell 具有极其通用的输出功能。开箱即用,它就拥有现代化的外观,带有颜色、ASCII 艺术和详细的错误消息。

以文本形式输出

默认情况下,像 ls 这样的命令的输出(正如我们所说,它生成结构化对象数组)显示为带有枚举行的彩色 ASCII 表格,其中每个文件是一行,每个属性是一列。例子

/usr/lib> ls | where name =~ ".*(alsa|pulse|pipewire).*" | first 10
╭───┬────────────────────────────┬─────────┬──────────┬──────────────╮
│ # │            name            │  type   │   size   │   modified   │
├───┼────────────────────────────┼─────────┼──────────┼──────────────┤
│ 0 │ alsa-lib                   │ dir     │   4.1 KB │ 2 days ago   │
│ 1 │ alsa-topology              │ dir     │   4.1 KB │ 3 months ago │
│ 2 │ libdrumstick-alsa.so       │ symlink │     22 B │ 7 months ago │
│ 3 │ libdrumstick-alsa.so.2     │ symlink │     26 B │ 7 months ago │
│ 4 │ libdrumstick-alsa.so.2.7.2 │ file    │ 335.3 KB │ 7 months ago │
│ 5 │ libgvncpulse-1.0.so        │ symlink │     21 B │ 9 months ago │
│ 6 │ libgvncpulse-1.0.so.0      │ symlink │     25 B │ 9 months ago │
│ 7 │ libgvncpulse-1.0.so.0.0.1  │ file    │  14.1 KB │ 9 months ago │
│ 8 │ libpipewire-0.3.so         │ symlink │     20 B │ 2 weeks ago  │
│ 9 │ libpipewire-0.3.so.0       │ symlink │     26 B │ 2 weeks ago  │
╰───┴────────────────────────────┴─────────┴──────────┴──────────────╯

以数据格式输出

数据也可以以各种数据格式输出,包括 JSON、YAML、TOML、HTML、XML、SQL、CSV、Markdown 表格等。用户还可以定义自己的自定义查看器以支持任意数据类型。

要以给定格式输出数据,只需将数据管道传输到 to FORMAT

/usr/lib> ls | where name =~ ".*alsa.*" | first 3 | to yaml
- name: alsa-lib
  type: dir
  size: 4096
  modified: 2023-05-03 16:04:35.544273606
- name: alsa-topology
  type: dir
  size: 4096
  modified: 2023-01-13 19:29:45.179245376
- name: libdrumstick-alsa.so
  type: symlink
  size: 22
  modified: 2022-10-02 13:28:57

要将命令的输出保存到文件中,请将其管道传输到 save 内置命令

> ls | to json | save my-file.json

如果输出文件已存在,save 将拒绝覆盖它。您可以使用 -f 开关强制覆盖文件。

请注意,nushell 默认生成美观打印的 JSON。要输出没有美观打印的 JSON,请使用 to json --raw

有关支持的格式列表,请参阅 to --help

错误输出

nushell 打印彩色且详细的错误消息,这些消息精确指出错误的来源并建议解决方案。错误消息示例

> ls -a --never-gonna-give-you-up /tmp
Error: nu::parser::unknown_flag

 × The `ls` command doesn't have flag `never-gonna-give-you-up`.
   ╭─[entry #24:1:1]
 1 │ ls -a --never-gonna-give-you-up /tmp
   ·       ────────────┬────────────
   ·                   ╰── unknown flag
   ╰────
  help: Available flags: --help(-h), --all(-a), --long(-l),
        --short-names(-s), --full-paths(-f), --du(-d), --directory(-D),
        --mime-type(-m). Use `--help` for more information.

输入

从数据文件输入

nushell 原生支持读取各种格式的数据,包括 JSON、YAML、TOML、SQL、HTML/XML 等,允许用户在其从任何文件格式读取的数据上利用其强大的数据查询和操作功能。用户还可以通过添加插件来添加对新格式的支持。

使用 open 内置命令从文件中读取数据。例如,假设我们有一个名为 movies.yaml 的文件,其内容如下

- movie: Matrix
  genre: Action
- movie: Lord of the Rings
  genre: [Action, Fantasy]
- movie: Independence Day
  genre: [Action, Sci-Fi]

然后执行 open movies.yaml 将产生以下输出

╭───┬───────────────────┬─────────────────╮
│ # │       movie       │      genre      │
├───┼───────────────────┼─────────────────┤
│ 0 │ Matrix            │ Action          │
│ 1 │ Lord of the Rings │ ╭───┬─────────╮ │
│   │                   │ │ 0 │ Action  │ │
│   │                   │ │ 1 │ Fantasy │ │
│   │                   │ ╰───┴─────────╯ │
│ 1 │ Independence Day  │ ╭───┬─────────╮ │
│   │                   │ │ 0 │ Action  │ │
│   │                   │ │ 1 │ Sci-Fi  │ │
│   │                   │ ╰───┴─────────╯ │
╰───┴───────────────────┴─────────────────╯

从外部程序输入

对于外部程序,它们通常以纯文本形式生成输出,nushell 提供了解析其输出并将其转换为结构化数据类型的能力,以便用户即使在不可知的程序生成的任意输出上也可以利用 nushell 的完整原生数据处理功能。

使用正则表达式解析

可以使用 parse 内置命令轻松执行解析外部程序输出。一种典型的工作流程是使用 -r 开关,该开关告诉 parse 使用正则表达式从输入中每行文本中提取字段。例如,要解析 pacman-Si 命令的输出,可以执行如下操作

> pacman -Si rclone | parse -r '(?P<name>.*\w) +: (?P<value>.+)'
╭────┬────────────────┬─────────────────────────────────────────────────╮
│  # │      name      │                    value                        │
├────┼────────────────┼─────────────────────────────────────────────────┤
│  0 │ Repository     │ extra                                           │
│  1 │ Name           │ rclone                                          │
│  2 │ Version        │ 1.62.2-1                                        │
│  3 │ Description    │ Sync files to and from Google Drive, S3, Swift, │
│    │                │ Cloudfiles, Dropbox and Google Cloud Storage    │
│  4 │ Architecture   │ x86_64                                          │
│  5 │ URL            │ https://rclone.org/                             │
│  6 │ Licenses       │ MIT                                             │
│  7 │ Groups         │ None                                            │
│  8 │ Provides       │ None                                            │
│  9 │ Depends On     │ glibc                                           │
│ 10 │ Optional Deps  │ fuse2: for rclone mount                         │
│ 11 │ Conflicts With │ None                                            │
│ 12 │ Replaces       │ None                                            │
│ 13 │ Download Size  │ 18.12 MiB                                       │
│ 14 │ Installed Size │ 75.93 MiB                                       │
│ 15 │ Packager       │ Morten Linderud <foxboron@archlinux.org>        │
│ 16 │ Build Date     │ Sun 02 Apr 2023 14:09:44 EEST                   │
│ 17 │ Validated By   │ MD5 Sum  SHA-256 Sum  Signature                 │
╰────┴────────────────┴─────────────────────────────────────────────────╯

nushell 使用类似 Perl 的正则表达式语法,该语法由 Regex crate(来自 Rust 编程语言)提供。该语法在 crate 的文档中描述。

使用模板字符串解析

另一种不需要正则表达式知识的方法是省略 -r 开关并为 parse 提供模板字符串。但是,根据具体情况,可能需要额外的步骤来预处理和后处理结果。例如

> pacman -Si just | lines | parse '{field} : {value}' | str trim

在这里,我们执行了与上述相同的任务,但有三个不同之处。除了使用模板字符串而不是正则表达式(即不使用 -r 开关)之外,第一个显着差异是,当 parse 获得模板字符串时,它作用于其输入的全部内容,而不是其中的每一行。因此,为了逐行解析输入,我们必须首先使用 lines 内置命令将其拆分为行数组。

第二个区别是模板字符串不会自动修剪多余的空格,这导致匹配的字段包含围绕它们的所有额外空格,因此我们必须使用 str trim 对输出进行后处理,这方便地作用于提供的数组中所有项目的所有字段。

数据操作

转换

opensave 内置命令的组合使其可以轻松地用于跨任何支持的格式转换数据文件。例如

然后可以通过将其管道传输到其他命令来自由操作或转换数据。例如

> open movies.yaml | first 2 | to json --raw
[{"movie": "Matrix","genre": "Action"},{"movie": "Lord of the Rings","genre":["Action","Fantasy"]}]
> open movies.yaml | first 2 | to json --raw | save movies.json
> cat movies.json
(same output as above)

与传统 Shell 的比较

本文或本节需要扩充。

原因:需要详细说明第一段中列举的一些要点。(在 Talk:Nushell 中讨论)

nushell 不是 POSIX shell,并且在许多方面与传统/POSIX 兼容的 shell 有显着差异,包括其语法、支持的内置命令、内置命令的工作方式、它们接受的命令行选项、它们消耗和生成的数据类型等等。

语法

将输出重定向到文件不能像其他 shell 那样使用 > 来完成。相反,您必须使用 save 内置命令。如果所讨论的输出恰好是复杂的数据结构(例如其内置命令 ls 的输出),则必须首先使用 to 内置命令将其序列化为文本表示形式。

因此,与其使用

ls > file.txt

您必须使用

ls | to yaml | save file.yaml

参见