Nushell 结构化 Shell¶
一句话说明: Nushell 是一种现代 Shell,将管道中的数据视为结构化表格(而非纯文本),原生支持 JSON/CSV/YAML 解析,让数据处理像查询数据库一样简单。
为什么要学¶
- 结构化管道 — 管道中传递的是表格/记录,不是字符串,告别
awk/sed/cut的文本拼接 - 内置数据格式支持 — 原生解析 JSON、CSV、TOML、YAML、XML,无需
jq等外部工具 - 类型安全 — 有类型系统,命令参数有类型检查,减少运行时错误
- 跨平台一致 — Windows/macOS/Linux 行为一致,不再区分 bash/zsh/powershell
- 友好的错误信息 — 彩色高亮、精确定位的错误提示
核心概念详解¶
传统 Shell vs Nushell¶
| 操作 | Bash | Nushell |
|---|---|---|
| 列出文件 | ls -la \| awk '{print $5,$9}' | ls \| select size name |
| 筛选文件 | ls \| grep .py | ls \| where name =~ ".py" |
| 排序 | ls -la \| sort -k5 -n | ls \| sort-by size |
| JSON 处理 | cat data.json \| jq '.items[].name' | open data.json \| get items.name |
| 进程查看 | ps aux \| grep python \| awk '{print $2}' | ps \| where name == "python" \| get pid |
数据类型¶
| 类型 | 说明 | 示例 |
|---|---|---|
table | 表格(行列结构) | ls 的输出 |
record | 记录(键值对) | {name: "hello", size: 42} |
list | 列表 | [1, 2, 3] |
string | 字符串 | "hello" |
int / float | 数字 | 42, 3.14 |
bool | 布尔 | true, false |
duration | 时间长度 | 5min, 2hr |
filesize | 文件大小 | 1gb, 500kb |
date | 日期时间 | 2024-01-01 |
管道模型¶
每个阶段传递的是结构化数据,不是文本行。
安装与配置¶
安装¶
# macOS
brew install nushell
# Linux (cargo)
cargo install nu
# Windows (winget)
winget install nushell
# Windows (scoop)
scoop install nu
设为默认 Shell¶
# 查找 nu 路径
which nu
# 添加到 /etc/shells(Linux/macOS)
echo $(which nu) | sudo tee -a /etc/shells
# 设为默认
chsh -s $(which nu)
配置文件¶
# 打开配置
nu> config nu # 编辑 config.nu
nu> config env # 编辑 env.nu
# 配置路径
# Linux: ~/.config/nushell/config.nu
# macOS: ~/Library/Application Support/nushell/config.nu
# Windows: %APPDATA%\nushell\config.nu
验证¶
快速上手¶
文件操作¶
# 列出文件(表格输出)
ls
# 筛选大文件
ls | where size > 1mb
# 按大小排序
ls | sort-by size --reverse | first 10
# 递归查找 Python 文件
glob **/*.py | each { |f| ls $f } | flatten
数据处理¶
# 打开 JSON 文件
open data.json
# 查询嵌套字段
open config.json | get database.host
# 打开 CSV 并过滤
open sales.csv | where amount > 1000 | sort-by date
# 转换格式
open data.json | to csv | save data.csv
系统信息¶
字符串操作¶
# 分割
"hello-world-test" | split row "-"
# 替换
"Hello World" | str replace "World" "Nushell"
# 正则匹配
ls | where name =~ '\.py$'
进阶用法¶
1. 自定义命令¶
# 定义命令(放入 config.nu)
def greet [name: string, --loud(-l)] {
let msg = $"Hello, ($name)!"
if $loud {
$msg | str upcase
} else {
$msg
}
}
# 使用
greet "World" --loud
# HELLO, WORLD!
2. HTTP 请求与 API 调用¶
# GET 请求(自动解析 JSON)
http get https://api.github.com/repos/nushell/nushell
| select stargazers_count forks_count open_issues_count
# POST 请求
http post https://httpbin.org/post {name: "test", value: 42}
3. 数据库式查询¶
# 分组统计
ls | group-by type | transpose key value | each { |row|
{type: $row.key, count: ($row.value | length)}
}
# 多文件聚合分析
glob *.csv | each { |f| open $f } | flatten
| where status == "error"
| group-by service
| transpose service errors
| insert count { |row| $row.errors | length }
| sort-by count --reverse
4. 管道与闭包¶
# each - 对每个元素操作
[1 2 3 4 5] | each { |x| $x * $x }
# [1, 4, 9, 16, 25]
# reduce - 累积
[1 2 3 4 5] | reduce { |it, acc| $acc + $it }
# 15
# par-each - 并行处理
glob *.png | par-each { |f| ^convert $f -resize 50% $"thumb_($f)" }
5. 环境变量与路径¶
# env.nu 中设置
$env.PATH = ($env.PATH | prepend "/usr/local/bin")
$env.EDITOR = "nvim"
# 临时修改
with-env {RUST_LOG: "debug"} { cargo run }
6. 错误处理¶
# try-catch
try {
open nonexistent.json
} catch {
print "文件不存在,使用默认配置"
{port: 8080, host: "localhost"}
}
7. 外部命令集成¶
# 调用外部命令(前缀 ^)
^git status
# 外部命令输出转为结构化数据
^docker ps --format "{{json .}}" | lines | each { |l| $l | from json }
# 混合管道
^kubectl get pods -o json | from json | get items | select metadata.name status.phase
常见问题与排错¶
Q: 某些 bash 语法不工作¶
Nushell 不是 POSIX Shell,以下语法不同: - 变量:$name(不是 $name 或 ${name}) - 字符串拼接:$"hello ($name)" - 管道:结构化数据,不是文本 - 条件:if $x > 0 { ... } 不是 [ $x -gt 0 ]
Q: 如何运行 bash 脚本¶
Q: PATH 配置不生效¶
在 env.nu(不是 config.nu)中配置 PATH:
Q: 命令输出是纯文本而非表格¶
外部命令默认返回字符串,需要手动解析:
Q: 如何安装插件¶
参考资源¶
- 官方文档:https://www.nushell.sh/book/
- GitHub 仓库:https://github.com/nushell/nushell
- 命令参考:https://www.nushell.sh/commands/
- Cookbook:https://www.nushell.sh/cookbook/
- 从 Bash 迁移:https://www.nushell.sh/book/coming_from_bash.html
- Discord 社区:https://discord.gg/NtAbbGn