nushell-usage
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseNushell Usage Patterns
Nushell 使用模式
Critical Distinctions
关键区别
Pipeline Input vs Parameters
管道输入 vs 参数
CRITICAL: Pipeline input () is NOT interchangeable with function parameters!
$innu
undefined重点注意:管道输入()与函数参数不可互换!
$innu
undefined❌ WRONG - treats $in as first parameter
❌ 错误写法 - 将$in视为第一个参数
def my-func [list: list, value: any] {
$list | append $value
}
def my-func [list: list, value: any] {
$list | append $value
}
✅ CORRECT - declares pipeline signature
✅ 正确写法 - 声明管道签名
def my-func [value: any]: list -> list {
$in | append $value
}
def my-func [value: any]: list -> list {
$in | append $value
}
Usage
使用示例
[1 2 3] | my-func 4 # Works correctly
my-func [1 2 3] 4 # ERROR! my-func doesn't take positional params
**This applies to closures too.**
**Why this matters**:
- Pipeline input can be **lazily evaluated** (streaming)
- Parameters are **eagerly evaluated** (loaded into memory)
- Different calling conventions entirely[1 2 3] | my-func 4 # 运行正常
my-func [1 2 3] 4 # 错误!my-func不接受位置参数
**此规则同样适用于闭包。**
**重要原因**:
- 管道输入支持**延迟求值**(流式处理)
- 参数是**立即求值**(加载至内存)
- 二者调用规则完全不同Type Signatures
类型签名
nu
undefinednu
undefinedNo pipeline input
无管道输入
def func [x: int] { ... } # (x) -> output
def func [x: int] { ... } # (x) -> 输出
Pipeline input only
仅管道输入
def func []: string -> int { ... } # string | func -> int
def func []: string -> int { ... } # string | func -> int
Both pipeline and parameters
同时支持管道与参数
def func [x: int]: string -> int { ... } # string | func x -> int
def func [x: int]: string -> int { ... } # string | func x -> int
Generic pipeline
通用管道
def func []: any -> any { ... } # works with any input type
undefineddef func []: any -> any { ... } # 支持任意输入类型
undefinedCommon Patterns
常见模式
Working with Lists
列表处理
nu
undefinednu
undefinedFilter with index
带索引过滤
$list | enumerate | where {|e| $e.index > 5 and $e.item.some-bool-field}
$list | enumerate | where {|e| $e.index > 5 and $e.item.some-bool-field}
Transform with previous state
基于前序状态转换
$list | reduce --fold 0 {|item, acc| $acc + $item.value}
undefined$list | reduce --fold 0 {|item, acc| $acc + $item.value}
undefinedWorking with Records
记录处理
nu
undefinednu
undefinedCreate record
创建记录
{name: "Alice", age: 30}
{name: "Alice", age: 30}
Merge records (right-biased)
合并记录(右偏置)
$rec1 | merge $rec2
$rec1 | merge $rec2
Merge many records (right-biased)
合并多条记录(右偏置)
[$rec1 $rec2 $rec3 $rec4] | into record
[$rec1 $rec2 $rec3 $rec4] | into record
Update field
更新字段
$rec | update name {|r| $"Dr. ($r.name)"}
$rec | update name {|r| $"Dr. ($r.name)"}
Insert field
插入字段
$rec | insert active true
$rec | insert active true
Insert field based on existing fields
基于现有字段插入新字段
{x:1, y: 2} | insert z {|r| $r.x + $r.y}
{x:1, y: 2} | insert z {|r| $r.x + $r.y}
Upsert (update or insert)
更新或插入字段(Upsert)
$rec | upsert count {|r| ($r.count? | default 0) + 1}
$rec | upsert count {|r| ($r.count? | default 0) + 1}
Reject fields
移除字段
$rec | reject password secret_key
$rec | reject password secret_key
Select fields
选择指定字段
$rec | select name age email
undefined$rec | select name age email
undefinedWorking with Tables
表格处理
nu
undefinednu
undefinedTables are lists of records
表格是记录的列表
let table = [
{name: "Alice", age: 30}
{name: "Bob", age: 25}
]
let table = [
{name: "Alice", age: 30}
{name: "Bob", age: 25}
]
Filter rows
过滤行
$table | where age > 25
$table | where age > 25
Add column
添加列
$table | insert retired {|row| $row.age > 65}
$table | insert retired {|row| $row.age > 65}
Rename column
重命名列
$table | rename -c {age: years}
$table | rename -c {age: years}
Group by
分组
$table | group-by status --to-table
$table | group-by status --to-table
Transpose (rows ↔ columns)
转置(行 ↔ 列)
$table | transpose name data
undefined$table | transpose name data
undefinedConditional Execution
条件执行
nu
undefinednu
undefinedIf expressions return values
if表达式返回值
let result = if $condition {
"yes"
} else {
"no"
}
let result = if $condition {
"是"
} else {
"否"
}
Match expressions
match表达式
let result = match $value {
0 => "zero"
1..10 => "small"
_ => "large"
}
undefinedlet result = match $value {
0 => "零"
1..10 => "小数值"
_ => "大数值"
}
undefinedNull Safety
空值安全
nu
undefinednu
undefinedOptional fields with ?
使用?处理可选字段
$record.field? # Returns null if missing
$record.field? | default "N/A" # Provide fallback
$record.field? # 字段不存在时返回null
$record.field? | default "无数据" # 提供默认值
Check existence
检查字段是否存在
if ($record.field? != null) { ... }
undefinedif ($record.field? != null) { ... }
undefinedError Handling
错误处理
nu
undefinednu
undefinedTry-catch
异常捕获(Try-catch)
try {
dangerous-operation
} catch {|err|
print $"Error: ($err.msg)"
}
try {
危险操作
} catch {|err|
print $"错误: ($err.msg)"
}
Returning errors
返回错误
def my-func [] {
if $condition {
error make {msg: "Something went wrong"}
} else {
"success"
}
}
def my-func [] {
if $condition {
error make {msg: "出现问题"}
} else {
"成功"
}
}
Check command success
检查命令执行结果
let result = try { fallible-command }
if ($result == null) {
# Handle error
}
let result = try { 可能失败的命令 }
if ($result == null) {
# 处理错误
}
Use complete for detailed error info for EXTERNAL commands (bins)
对外部命令(二进制文件)使用complete获取详细错误信息
let result = (fallible-external-command | complete)
if $result.exit_code != 0 {
print $"Error: ($result.stderr)"
}
undefinedlet result = (可能失败的外部命令 | complete)
if $result.exit_code != 0 {
print $"错误: ($result.stderr)"
}
undefinedClosures and Scoping
闭包与作用域
nu
undefinednu
undefinedClosures capture environment
闭包捕获环境变量
let multiplier = 10
let double_and_add = {|x| ($x * 2) + $multiplier}
5 | do $double_and_add # Returns 20
let multiplier = 10
let double_and_add = {|x| ($x * 2) + $multiplier}
5 | do $double_and_add # 返回20
Outer mutable variables CANNOT be captured in closures
外部可变变量无法被闭包捕获
mut sum = 0
[1 2 3] | each {|x| $sum = $sum + $x} # ❌ WON'T COMPILE
mut sum = 0
[1 2 3] | each {|x| $sum = $sum + $x} # ❌ 无法编译
Use reduce instead
改用reduce
let sum = [1 2 3] | reduce {|x, acc| $acc + $x}
undefinedlet sum = [1 2 3] | reduce {|x, acc| $acc + $x}
undefinedIteration Patterns
迭代模式
nu
undefinednu
undefinedeach: transform each element
each: 转换每个元素
$list | each {|item| $item * 2}
$list | each {|item| $item * 2}
each --flatten: stream outputs instead of collecting
each --flatten: 流式输出而非收集结果
Turns list<list<T>> into list<T> by streaming items as they arrive
将list<list<T>>转换为list<T>,处理完成后立即输出元素
ls *.txt | each --flatten {|f| open $f.name | lines } | find "TODO"
ls *.txt | each --flatten {|f| open $f.name | lines } | find "TODO"
each --keep-empty: preserve null results
each --keep-empty: 保留空结果
[1 2 3] | each --keep-empty {|e| if $e == 2 { "found" }}
[1 2 3] | each --keep-empty {|e| if $e == 2 { "找到" }}
Result: ["" "found" ""] (vs. without flag: ["found"])
结果: ["" "找到" ""] (不使用该标志时结果为: ["找到"])
filter/where: select elements
filter/where: 选择元素
Row condition (field access auto-uses $it)
行条件(字段访问自动使用$it)
$table | where size > 100 # Implicit: $it.size > 100
$table | where type == "file" # Implicit: $it.type == "file"
$table | where size > 100 # 等价于: $it.size > 100
$table | where type == "file" # 等价于: $it.type == "file"
Closure (must use $in or parameter)
闭包(必须使用$in或参数名)
$list | where {|x| $x > 10}
$list | where {$in > 10} # Same as above
$list | where {|x| $x > 10}
$list | where {$in > 10} # 与上面等价
reduce/fold: accumulate
reduce/fold: 累加
$list | reduce --fold 0 {|item, acc| $acc + $item}
$list | reduce --fold 0 {|item, acc| $acc + $item}
Reduce without fold (first element is initial accumulator)
不指定初始值的reduce(第一个元素作为初始累加值)
[1 2 3 4] | reduce {|it, acc| $acc - $it} # ((1-2)-3)-4 = -8
[1 2 3 4] | reduce {|it, acc| $acc - $it} # ((1-2)-3)-4 = -8
par-each: parallel processing
par-each: 并行处理
$large_list | par-each {|item| expensive-operation $item}
$large_list | par-each {|item| 耗时操作 $item}
for loop (imperative style)
for循环(命令式风格)
for item in $list {
print $item
}
undefinedfor item in $list {
print $item
}
undefinedString Manipulation
字符串处理
nu
undefinednu
undefinedInterpolation
插值
$"Hello ($name)!"
$"Sum: (1 + 2)" # "Sum: 3"
$"你好 ($name)!"
$"总和: (1 + 2)" # "总和: 3"
Split/join
分割/连接
"a,b,c" | split row "," # ["a", "b", "c"]
["a", "b"] | str join ", " # "a, b"
"a,b,c" | split row "," # ["a", "b", "c"]
["a", "b"] | str join ", " # "a, b"
Regex
正则表达式
"hello123" | parse --regex '(?P<word>\w+)(?P<num>\d+)'
"hello123" | parse --regex '(?P<word>\w+)(?P<num>\d+)'
Multi-line strings
多行字符串
$"
Line 1
Line 2
"
undefined$"
第一行
第二行
"
undefinedGlob Patterns (File Matching)
通配符模式(文件匹配)
nu
undefinednu
undefinedBasic patterns
基础模式
glob .rs # All .rs files in current dir
glob **/.rs # Recursive .rs files
glob **/*.{rs,toml} # Multiple extensions
**Note**: Prefer `glob` over `find` or `ls` for file searches - it's more efficient and has better pattern support.glob .rs # 当前目录下所有.rs文件
glob **/.rs # 递归查找所有.rs文件
glob **/*.{rs,toml} # 匹配多种扩展名
**注意**:文件搜索优先使用`glob`而非`find`或`ls`——它更高效,且模式支持更完善。Module System
模块系统
nu
undefinednu
undefinedDefine module
定义模块
module my_module {
export def public-func [] { ... }
def private-func [] { ... }
export const MY_CONST = 42}
module my_module {
export def public-func [] { ... }
def private-func [] { ... }
export const MY_CONST = 42}
Use module
使用模块
use my_module *
use my_module [public-func MY_CONST]
use my_module *
use my_module [public-func MY_CONST]
Import from file
从文件导入
use lib/helpers.nu *
undefineduse lib/helpers.nu *
undefinedRow Conditions vs Closures
行条件 vs 闭包
Many commands accept either a row condition or a closure:
许多命令支持行条件或闭包两种写法:
Row Conditions (Short-hand Syntax)
行条件(简写语法)
nu
undefinednu
undefinedAutomatic $it expansion on left side
左侧自动展开$it
$table | where size > 100 # Expands to: $it.size > 100
$table | where name =~ "test" # Expands to: $it.name =~ "test"
$table | where size > 100 # 展开为: $it.size > 100
$table | where name =~ "test" # 展开为: $it.name =~ "test"
Works with: where, filter (DEPRECATED, use where), find, skip while, take while, etc.
适用命令: where, filter(已废弃,使用where), find, skip while, take while等
ls | where type == file # Simple and readable
**Limitations**:
- Cannot be stored in variables
- Only field access on left side auto-expands
- Subexpressions need explicit `$it`:
```nu
ls | where ($it.name | str downcase) =~ readme # Need $it herels | where type == file # 简洁易读
**局限性**:
- 无法存储为变量
- 仅左侧字段访问自动展开
- 子表达式需显式使用`$it`:
```nu
ls | where ($it.name | str downcase) =~ readme # 此处必须使用$itClosures (Full Flexibility)
闭包(完全灵活)
nu
undefinednu
undefinedUse $in or parameter name
使用$in或参数名
$table | where {|row| $row.size > 100}
$table | where {$in.size > 100}
$table | where {|row| $row.size > 100}
$table | where {$in.size > 100}
Can be stored and reused
可存储并复用
let big_files = {|row| $row.size > 1mb}
ls | where $big_files
let big_files = {|row| $row.size > 1mb}
ls | where $big_files
Works anywhere
适用于所有场景
$list | each {|x| $x * 2}
$list | where {$in > 10}
**When to use**:
- Row conditions: Simple field comparisons (cleaner syntax)
- Closures: Complex logic, reusable conditions, nested operations$list | each {|x| $x * 2}
$list | where {$in > 10}
**使用场景**:
- 行条件:简单字段比较(语法更简洁)
- 闭包:复杂逻辑、可复用条件、嵌套操作Common Pitfalls
常见陷阱
each
on Single Records
each对单个记录使用each
nu
undefinednu
undefined❌ Don't pass single records to each
❌ 不要对单个记录使用each
let record = {a: 1, b: 2}
$record | each {|field| print $field} # Only runs once!
let record = {a: 1, b: 2}
$record | each {|field| print $field} # 仅执行一次!
✅ Use items, values, or transpose instead
✅ 改用items、values或transpose
$record | items {|key, val| print $"($key): ($val)"}
$record | transpose key val | each {|row| ...}
undefined$record | items {|key, val| print $"($key): ($val)"}
$record | transpose key val | each {|row| ...}
undefinedPipe vs Call Ambiguity
管道与调用的歧义
nu
undefinednu
undefinedThese are different!
这两种写法完全不同!
$list | my-func arg1 arg2 # $list piped, arg1 & arg2 as params
my-func $list arg1 arg2 # All three as positional params (if signature allows)
undefined$list | my-func arg1 arg2 # $list作为管道输入,arg1和arg2作为参数
my-func $list arg1 arg2 # 三者均为位置参数(需函数签名支持)
undefinedOptional Fields
可选字段
nu
undefinednu
undefined❌ Error if field doesn't exist
❌ 字段不存在时会报错
$record.missing # ERROR
$record.missing # 错误
✅ Use ?
✅ 使用?
$record.missing? # null
$record.missing? | default "N/A" # "N/A"
undefined$record.missing? # 返回null
$record.missing? | default "无数据" # 返回"无数据"
undefinedEmpty Collections
空集合
nu
undefinednu
undefinedEmpty list/table checks
检查列表/表格是否为空
if ($list | is-empty) { ... }
if ($list | is-empty) { ... }
Default value if empty
为空时使用默认值
$list | default -e $val_if_empty
undefined$list | default -e $空集合默认值
undefinedAdvanced Topics
进阶主题
For advanced patterns and deeper dives, see:
- references/advanced-patterns.md - Performance optimization, lazy evaluation, streaming, closures, memory-efficient patterns
- references/type-system.md - Complete type system guide, conversions, generics, type guards
如需了解进阶模式与深度内容,请参考:
- references/advanced-patterns.md - 性能优化、延迟求值、流式处理、闭包、内存高效模式
- references/type-system.md - 完整类型系统指南、类型转换、泛型、类型守卫
Best Practices
最佳实践
- Use type signatures - helps catch errors early
- Prefer pipelines - more idiomatic and composable
- Document with comments - for inline, also
#above declarations for doc comments# - Export selectively - don't pollute namespace
- Use - handle null/missing gracefully
default - Validate inputs - check types/ranges at function start
- Return consistent types - don't mix null and values unexpectedly
- Use modules - organize related functions
- Test incrementally - build complex pipelines step-by-step
- Prefix external commands with caret - instead of just
^grep. Makes it clear it's not a nushell command, avoids ambiguity. Nushell commands always have precedence, e.g.grepis NOT usual Unixfindtool: usefind.^find - Use dedicated external commands when needed - searching through lots of files is still faster with or
grep, and large nested JSON structures will be processed much faster byrgjq
- 使用类型签名 - 提前捕获错误
- 优先使用管道 - 更符合Nushell风格且可组合
- 添加注释文档 - 用写行内注释,也可在声明上方写文档注释
# - 选择性导出 - 避免污染命名空间
- 使用default - 优雅处理null/缺失值
- 验证输入 - 在函数开头检查类型/范围
- 返回一致类型 - 避免意外混合null与有效值
- 使用模块 - 组织相关函数
- 增量测试 - 逐步构建复杂管道
- 外部命令加^前缀 - 使用而非
^grep,明确标识为外部命令,避免歧义。Nushell命令优先级更高,例如grep不是Unix的find工具,需使用find。^find - 必要时使用专用外部命令 - 大量文件搜索用或
grep更快,大型嵌套JSON结构用rg处理效率更高jq
Debugging Techniques
调试技巧
nu
undefinednu
undefinedPrint intermediate values
打印中间值
$data | each {|x| print $x; $x} # Prints and passes through
$data | each {|x| print $x; $x} # 打印后传递值
Inspect type
查看类型
$value | describe
$value | describe
Debug point
调试断点
debug # Drops into debugger (if available)
debug # 进入调试器(若可用)
Timing
计时
timeit { expensive-command }
undefinedtimeit { 耗时命令 }
undefined