
Nushell 如何用 from nuon 和 to nuon 读写带注释、尾随逗号与表格形式的 NUON 文件【免费下载链接】nushellA new type of shell项目地址: https://gitcode.com/GitHub_Trending/nu/nushell当数据文件由人手工编写或审阅时JSON 往往显得啰嗦每行都要重复键名不能写注释尾随逗号还会直接报错。Nushell 内置的 NUON 格式Nushell Object Notation解决了这些问题。from nuon把 NUON 文本反序列化为结构化数据to nuon把 Nushell 值序列化为 NUON 文本两个命令都属于 Formats 类别随 Nushell 发布即可使用。本文按仓库中 crates/nuon/README.md、正式规范 和 命令实现 中的真实示例走一遍“读入带注释、尾随逗号与表格形式的 NUON → 改造成想要的输出风格 → 验证往返一致”的完整路径。前提NUON 是 JSON 的超集外加表格形式按 crates/nuon/README.md 的定义NUON 在 JSON 基础上增加了允许尾随逗号列表中的逗号本身也是可选的用空白分隔也可以键和不包含空格、特殊字符的字符串可以不带引号允许#注释——但from nuon不会保留注释数字支持十六进制、八进制、二进制可带_分隔符可以以或孤立的.开头2min、1kb、2000-01-01T00:00:0000:00这类 duration、filesize、datetime 是字面量0x[be ef]、$.a.b、1..5分别是 binary、cell-path 和 range一组结构一致的 record 列表可以写成表格形式列名只写一次而不是每行重复。同一段数据两种写法的对照示例取自 README{ name: Some One, birth: 1970-01-01, stats: [ 2544729499973429198, 687051042647753531, 6702443901704799912 ] }{ name: Some One, # the name of the person birth: 1970-01-01, # their date of birth stats: [ # some dummy stats about them 2544729499973429198, 687051042647753531, 6702443901704799912, # note the trailing comma here... ], # and here } # wait, are these comments in a JSON-like document?!?!NUON 文件就是 UTF-8 文本文件规范要求输入必须是合法的 UTF-8开头的 BOM 会被剥掉恰好一个。所有读写都是通过管道把文本交给这两个命令完成的。用 from nuon 读入带注释与尾随逗号的文档from nuon的签名是字符串输入、任意类型输出from nuon 实现命令文档给出的可直接执行示例{ a:1 } | from nuon # 结果record { a: 1 } { a:1, b: [1, 2] } | from nuon # 结果record { a: 1, b: [1 2] } {a:1,b:[1,2]} | from nuon # 结果record { a: 1, b: [1 2] }带注释和尾随逗号的文档能直接读入示例输出取自正式规范规范约定其中的nushell代码块是“带真实输出的命令”[1, 2, 3,] | from nuon | to json -r # [1,2,3]注意#成为注释是有条件的只在 token 边界处输入开头、空白、或, : [ ] { } ;之后才算注释符紧贴在前一个词后面时就是普通字符。这两条对照来自规范判断你的文档里#到底起了什么作用[a#b] | from nuon | to json -r # [a#b] [a, # note\n b] | from nuon | to json -r # [a,b]读入后注释被丢弃这是 README 明确说明的行为允许注释但from_nuon不保留它们。表格形式列名只写一次表格形式的语法是[ 表头; 行1 行2 ... ]表头和每一行都是列表行单元格按位置对应表头列名。解码后它就是一组 record 的列表与逐行写 record 没有区别[[a b]; [1 2] [3 4]] | from nuon | to json -r # [{a:1,b:2},{a:3,b:4}]README 里用 3 行 4 列的例子展示了压缩效果同样的数据在 JSON 里要重复每个键NUON 表格形式把 20 行压成 6 行四个列名只写了一次。写表格文件时有几条硬规则违规会直接报错而不是静默出错以下均为规范中的文档示例# 表头必须是字符串 [[a 1]; [1 2]] | from nuon # error # 行长度必须与表头一致 [[a b]; [1]] | from nuon # error # 列名不能重复 [[a b a]; [1 2 3]] | from nuon # error: column_defined_twice另外“有表头但没有数据行”在表格形式下无法表达空表只能写[]。用 to nuon 写出 NUON并控制输出风格to nuon接受任意输入、输出字符串默认是紧凑的单行输出。命令文档 中经过测试的示例[1 2 3] | to nuon # 结果[1, 2, 3] [1 2 3] | to nuon --indent 2 # 结果 # [ # 1, # 2, # 3 # ] {date: 2000-01-01, data: [1 [2 3] 4.56]} | to nuon --indent 2 # 结果 # { # date: 2000-01-01T00:00:0000:00, # data: [ # 1, # [ # 2, # 3 # ], # 4.56 # ] # }注意 date 值被写成完整的 RFC 3339 形式writer 对 datetime 总是输出完整形式规范示例{date: 2000-01-01} | to nuon # {date: 2000-01-01T00:00:0000:00}。to nuon的全部开关及默认值规范给出的表除特别说明外默认全部关闭开关短参数默认作用--raw-r关去掉所有空白--indent N-i关每项一行每层缩进 N 个空格--tabs N-t关每项一行每层缩进 N 个制表符--pretty-p关等价于--indent 2--list-of-records-l关不用表格形式逐行输出 record--no-commas-c关用空白代替逗号分隔--raw-strings-R关把含引号或反斜杠的字符串写成r#...#--serialize-s关把无法反序列化回来的类型序列化为字符串开关冲突时的优先级规则也是规范明确写死的判断输出形态时按这个顺序--raw压过--indent、--tabs、--pretty[[a b]; [1 2]] | to nuon --pretty --raw结果是[[a,b];[1,2]]--tabs压过--indent--indent 0与--tabs 0等价于--raw--raw不压过--list-of-records和--raw-strings这两者可以与它组合[[a b]; [1 2]] | to nuon --raw --list-of-records结果是[{a:1,b:2}]--raw与--no-commas互斥前者删空白、后者用空白当分隔符同时用会没有分隔符[1 2 3]会被读回成整数123。几个常用分支的输出均为命令文档或规范中的示例[[a, b]; [1, 2], [3, 4]] | to nuon --list-of-records # [{a: 1, b: 2}, {a: 3, b: 4}] [1 2 3] | to nuon --no-commas # [1 2 3] {a: 1, b: 2} | to nuon --no-commas # {a: 1 b: 2} helloworld.into | to nuon --raw # 文档示例--raw 覆盖其它缩进选项 [1 2 3] | to nuon --indent 2 --raw # [1,2,3] hello world | to nuon --raw-strings # r#hello world# [[name, age]; [Alice, 30], [Bob, 25]] | to nuon --pretty # [ # [name, age]; # [Alice, 30], # [Bob, 25] # ]--pretty会同时对齐表格列--indent走的是同一条代码路径所以--indent N也会对齐列。--list-of-records下即使带缩进每个 record 仍会内联在一行里。何时自动使用表格形式何时不会to nuon不是无条件把列表写成表格。规范给出的判定条件列表非空、每个元素都是 record、record 至少有一个键、且所有 record 键相同且顺序相同才会用表格形式键顺序不同就会被判成普通列表[{a: 1, b: 2}, {b: 3, a: 4}] | to nuon # [{a: 1, b: 2}, {b: 3, a: 4}] [{}, {}] | to nuon # [{}, {}]想强制不用表格形式时加--list-of-records它会无条件关闭表格语法。验证往返一致性与输出类型最直接的验证是读写往返。规范值模型一节给出的例子说明 binary、cell-path、range 三类值能完整往返即from nuon读得回to nuon写出的所有内容[0x[be ef], $.a.b, 1..5] | from nuon | to nuon # [0x[BEEF], $.a.b, 1..5]也可以用metadata检查to nuon产物携带的内容类型该断言来自 to nuon 命令测试{a: 1 b: 2} | to nuon | metadata | get content_type # 结果application/x-nuon读入失败时的报错信息来自 from nuon 实现 的错误分支可按消息文本定位原因error when loading nuon text/could not load nuon text——外层包装error when parsing nuon text——语法解析失败table has mismatched columns——表格行与表头长度不一致only strings can be keys——表头/键不是字符串column_defined_twice即规范中写的error: column_defined_twice——record 键或表格列名重复excess values when loading——输入里不止一个顶层值detected a pipeline in nuon file——输入里出现了管道variables not supported in nuon、calls not supported in nuon等——NUON 只是数据格式变量、命令调用、闭包、子表达式都不允许。限制与边界注释只在读入时存在from nuon不保留注释to nuon也不会生成注释。带注释的文件经过一次往返后注释会消失。writer 的引号规则字符串只有在满足“非空、不含强制加引号字符集、不含 Unicode 空白、不含任何十进制数字类别Nd、读回来仍是字符串”时才不加引号。所以a1会被加引号而a-b不会[a1 0x abc x-1 a-b a_b 1s E5 3/4] | to nuon # [a1, 0x, abc, x-1, a-b, a_b, 1s, E5, 3/4]规范特别警告0x、0o8、0b2这类普通字符串如果裸写reader 会提交到进制字面量解析然后报错即产生“自己都打不开的文件”——writer 的加引号逻辑就是为了避免这种情况。duration 和 filesize 的写回形式writer 对 duration 一律输出ns[1sec] | to nuon # [1000000000ns]filesize 一律输出b[1kb] | to nuon # [1000b]读入时的2min、1kb形式只在文件里存在。裸词不能单独成文abc | from nuon是错误裸词只能在列表、record 等结构内部使用顶层单独一个字符串会被 writer 加引号hi | to nuon # hi[hi] | to nuon # [hi]。不能序列化的类型closure 默认报错提示use --serialize to serialize as a stringcustom value 直接报custom values are currently not nuon-compatible。按规范--serialize实际只对 closure 和 block 生效binary、cell-path、range 无论是否加该开关都原生写出glob 无论如何都会变成普通字符串。完整的语法定义、单位后缀表和逐条的合规检查清单见 crates/nuon/spec/nuon_formal_specification.md规范中还维护了 bugs_to_fix.md 追踪当前实现与规范仍不一致的地方读入行为与上述规则有出入时可以对照该文件。【免费下载链接】nushellA new type of shell项目地址: https://gitcode.com/GitHub_Trending/nu/nushell创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考