nushell-usage

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Nushell Usage Patterns

Nushell 使用模式

Critical Distinctions

关键区别

Pipeline Input vs Parameters

管道输入 vs 参数

CRITICAL: Pipeline input (
$in
) is NOT interchangeable with function parameters!
nu
undefined
重点注意:管道输入(
$in
)与函数参数不可互换!
nu
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
undefined
nu
undefined

No 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
undefined
def func []: any -> any { ... } # 支持任意输入类型
undefined

Common Patterns

常见模式

Working with Lists

列表处理

nu
undefined
nu
undefined

Filter 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}
undefined

Working with Records

记录处理

nu
undefined
nu
undefined

Create 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
undefined

Working with Tables

表格处理

nu
undefined
nu
undefined

Tables 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
undefined

Conditional Execution

条件执行

nu
undefined
nu
undefined

If 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" }
undefined
let result = match $value { 0 => "零" 1..10 => "小数值" _ => "大数值" }
undefined

Null Safety

空值安全

nu
undefined
nu
undefined

Optional 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) { ... }
undefined
if ($record.field? != null) { ... }
undefined

Error Handling

错误处理

nu
undefined
nu
undefined

Try-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)" }
undefined
let result = (可能失败的外部命令 | complete) if $result.exit_code != 0 { print $"错误: ($result.stderr)" }
undefined

Closures and Scoping

闭包与作用域

nu
undefined
nu
undefined

Closures 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}
undefined
let sum = [1 2 3] | reduce {|x, acc| $acc + $x}
undefined

Iteration Patterns

迭代模式

nu
undefined
nu
undefined

each: 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 }
undefined
for item in $list { print $item }
undefined

String Manipulation

字符串处理

nu
undefined
nu
undefined

Interpolation

插值

$"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
$" 第一行 第二行 "
undefined

Glob Patterns (File Matching)

通配符模式(文件匹配)

nu
undefined
nu
undefined

Basic 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
undefined
nu
undefined

Define 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 *
undefined
use lib/helpers.nu *
undefined

Row Conditions vs Closures

行条件 vs 闭包

Many commands accept either a row condition or a closure:
许多命令支持行条件闭包两种写法:

Row Conditions (Short-hand Syntax)

行条件(简写语法)

nu
undefined
nu
undefined

Automatic $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 here
ls | where type == file # 简洁易读

**局限性**:
- 无法存储为变量
- 仅左侧字段访问自动展开
- 子表达式需显式使用`$it`:
  ```nu
  ls | where ($it.name | str downcase) =~ readme  # 此处必须使用$it

Closures (Full Flexibility)

闭包(完全灵活)

nu
undefined
nu
undefined

Use $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

nu
undefined
nu
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| ...}
undefined

Pipe vs Call Ambiguity

管道与调用的歧义

nu
undefined
nu
undefined

These 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 # 三者均为位置参数(需函数签名支持)
undefined

Optional Fields

可选字段

nu
undefined
nu
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 "无数据" # 返回"无数据"
undefined

Empty Collections

空集合

nu
undefined
nu
undefined

Empty 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 $空集合默认值
undefined

Advanced 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

最佳实践

  1. Use type signatures - helps catch errors early
  2. Prefer pipelines - more idiomatic and composable
  3. Document with comments -
    #
    for inline, also
    #
    above declarations for doc comments
  4. Export selectively - don't pollute namespace
  5. Use
    default
    - handle null/missing gracefully
  6. Validate inputs - check types/ranges at function start
  7. Return consistent types - don't mix null and values unexpectedly
  8. Use modules - organize related functions
  9. Test incrementally - build complex pipelines step-by-step
  10. Prefix external commands with caret -
    ^grep
    instead of just
    grep
    . Makes it clear it's not a nushell command, avoids ambiguity. Nushell commands always have precedence, e.g.
    find
    is NOT usual Unix
    find
    tool: use
    ^find
    .
  11. Use dedicated external commands when needed - searching through lots of files is still faster with
    grep
    or
    rg
    , and large nested JSON structures will be processed much faster by
    jq
  1. 使用类型签名 - 提前捕获错误
  2. 优先使用管道 - 更符合Nushell风格且可组合
  3. 添加注释文档 - 用
    #
    写行内注释,也可在声明上方写文档注释
  4. 选择性导出 - 避免污染命名空间
  5. 使用default - 优雅处理null/缺失值
  6. 验证输入 - 在函数开头检查类型/范围
  7. 返回一致类型 - 避免意外混合null与有效值
  8. 使用模块 - 组织相关函数
  9. 增量测试 - 逐步构建复杂管道
  10. 外部命令加^前缀 - 使用
    ^grep
    而非
    grep
    ,明确标识为外部命令,避免歧义。Nushell命令优先级更高,例如
    find
    不是Unix的
    find
    工具,需使用
    ^find
  11. 必要时使用专用外部命令 - 大量文件搜索用
    grep
    rg
    更快,大型嵌套JSON结构用
    jq
    处理效率更高

Debugging Techniques

调试技巧

nu
undefined
nu
undefined

Print 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 }
undefined
timeit { 耗时命令 }
undefined

External Resources

外部资源