ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Miller 分隔符完全指南:记录、字段与键值对分隔符(RS/FS/PS)的配置与实战

Miller 分隔符完全指南:记录、字段与键值对分隔符(RS/FS/PS)的配置与实战 CLI数据分析【免费下载链接】millerMiller is like awk, sed, cut, join, and sort for name-indexed data such as CSV, TSV, and tabular JSON项目地址https://gitcode.com/gh_mirrors/mi/miller点击查看免费下载Miller 把文本数据切分为记录、字段、键值对三层并分别用记录分隔符RS、字段分隔符FS与键值对分隔符PS来控制切分与拼接。本文以 Miller 官方参考文档 docs/src/reference-main-separators.md 为主体完整讲解--irs/--ors、--ifs/--ofs、--ips/--ops及--rs/--fs/--ps、--repifs、--ifs-regex/--ips-regex等全套分隔符命令行参数并对照仓库源码 pkg/cli/separators.go 与 pkg/cli/option_parse.go 讲清其底层实现。读完本文你将能够在 DKVP、CSV、TSV、NIDX、XTAB 等任意格式之间自由切换分隔符实现数据格式的无缝转换。记录分隔符、字段分隔符与键值对分隔符Miller 从三个层次来理解分隔符记录分隔符record separatorRS把一条条记录分开字段分隔符field separatorFS把一条记录里的各个字段即键值对分开键值对分隔符pair separatorPS把每个字段内部的键与值分开。以经典的 DKVP 键值对格式 为例数据文件 docs/src/data/a.dkvp 内容如下cat docs/src/data/a.dkvpa1,b2,c3 a4,b5,c6在这两行数据中记录分隔符是换行符——它把a1,b2,c3与a4,b5,c6两条记录分开字段分隔符是,——它把a1、b2、c3这三个键值对字段分开键值对分隔符是——它把每个字段内的键如a与值如1分开。以上是 Miller 的默认值可通过--ips、--ops等 flag 覆盖详见下文。需要特别说明的是并非所有文件格式都同时具备这三类分隔符。例如 CSV 就没有键值对分隔符——因为 CSV 的键表头独占一行值独占一行键和值并不相邻。同样分隔符也并非对所有文件格式都可编程。例如在 JSON 对象 中键值对分隔符是:、字段分隔符是,写作{a:1,b:2,c:3}但这两者都不可修改。即便执行mlr --json --ips : --ips cat myfile.json你也不会得到{a1,b2,c3}——因为键值对分隔符:是 JSON 规范的一部分Miller 不会、也不能改变它。这一点在源码中也有对应在 pkg/cli/separators.go 的defaultPSes表中json、yaml、dcf、recutils等格式的 PS 一律标注为N/A不可变更、不可参数化。输入与输出分隔符IRS/ORS、IFS/OFS、IPS/OPSMiller 允许输入与输出使用相同的分隔符如 CSV 输入、CSV 输出也允许在输入与输出之间更换分隔符如 CSV 输入、JSON 输出从而实现数据的格式转换。Miller 使用以下命名体系IRS与ORS输入记录分隔符与输出记录分隔符IFS与OFS输入字段分隔符与输出字段分隔符IPS与OPS输入键值对分隔符与输出键值对分隔符。例如把输入为逗号/等号风格的 DKVP 数据转换为输出为分号/冒号风格的数据mlr --ifs , --ofs ; --ips --ops : cut -o -f c,a,b docs/src/data/a.dkvpc:3;a:1;b:2 c:6;a:4;b:5这里cut -o -f c,a,b把字段顺序重排为c,a,b同时输入侧按,与解析输出侧按;与:写回。再看 CSV 场景。CSV 没有键值对分隔符但字段分隔符同样可以自由切换mlr --csv head -n 2 docs/src/example.csvcolor,shape,flag,k,index,quantity,rate yellow,triangle,true,1,11,43.6498,9.8870 red,square,true,2,15,79.2778,0.0130mlr --csv --ofs pipe head -n 2 docs/src/example.csvcolor|shape|flag|k|index|quantity|rate yellow|triangle|true|1|11|43.6498|9.8870 red|square|true|2|15|79.2778|0.0130只加了一个--ofs pipe输出字段分隔符就从逗号变成了管道符|。双向同设的快捷 flag--rs、--fs、--ps如果数据的输入输出分隔符相同、不需要分别设置可以使用--rs、--fs、--ps。例如--fs :与--ifs : --ofs :完全等价但敲击键盘的次数更少。以使用分号作字段分隔符、冒号作键值对分隔符的 DKVP 数据 docs/src/data/modsep.dkvp 为例cat docs/src/data/modsep.dkvpa:1;b:2;c:3 a:4;b:5;c:6mlr --fs ; --ps : cut -o -f c,a,b docs/src/data/modsep.dkvpc:3;a:1;b:2 c:6;a:4;b:5从源码看--rs、--fs、--ps的解析器会同时把值写入ReaderOptions与WriterOptions例如 pkg/cli/option_parse.go 中--fs的解析器同时设置options.ReaderOptions.IFS与options.WriterOptions.OFS并分别标记ifsWasSpecified与ofsWasSpecified。这就是一个 flag 同时作用于输入与输出的实现机制。多字符分隔符除少数不允许参数化的文件格式外所有分隔符都可以是多字符的。但注意对于 CSVCSV-lite 没有这些限制IRS必须是\n且IFS必须是单字符。例如把输入的分号/冒号数据输出为三连分号;;;与:风格mlr --ifs ; --ips : --ofs ;;; --ops : cut -o -f c,a,b docs/src/data/modsep.dkvpc:3;;;a:1;;;b:2 c:6;;;a:4;;;b:5输入侧照旧按单字符;与:解析输出侧则按多字符;;;与:拼接充分体现了 Miller 输入/输出分隔符相互独立的设计。--repifs把连续重复的分隔符视为一个如果数据中的字段分隔符是一个或多个连续空格可以使用--ifs space --repifs来解析。更一般地--repifs表示字段分隔符的多次连续出现只算作一次。两种常见的处理语义对比在 CSV 数据中我们常用空字符串表示空值例如2,9,,,,,6,5,4——这里每个逗号都是有效分隔连续逗号之间是空字段必须保留但如果字段分隔符是空格把2 4 5解析成与2 4 5相同往往更自然——此时--repifs --ifs 就能实现这个效果。实际上--ipprint选项在内部就是用--repifs实现的。从源码看pkg/cli/separators.go 的defaultAllowRepeatIFSes表中pprint格式的默认值即为true而 CSV、DKVP、TSV 等格式默认为false——也就是说 PPRINT 格式天生就允许重复分隔符用空格对齐其余格式则需要显式传入--repifs才会开启。来看官方示例数据文件 docs/src/data/extra-spaces.txtcat docs/src/data/extra-spaces.txtoh say can you see by the dawns early light what somlr --ifs --repifs --inidx --oxtab cat docs/src/data/extra-spaces.txt1 oh 2 say 3 can 4 you 1 see 2 by 3 the 4 dawns 1 early 2 light 3 what 4 so--inidx把每条记录当作 NIDX索引编号格式读入——字段没有名字自动按位置编号 1、2、3、4--oxtab则输出为 XTAB 竖向表格。行内多个连续空格都被折叠成一个字段分隔所以oh say can you被正确切成了 4 个字段。正则表达式分隔符--ifs-regex 与 --ips-regexIFS和IPS可以是正则表达式使用--ifs-regex或--ips-regex代替--ifs或--ips即可。例如--ifs space --repifs和--ifs-regex ( )都能实现连续空格算一个分隔的效果。但官方文档特别提示--ifs space --repifs比--ifs-regex ( )大约快 3 倍——正则表达式功能强大但速度更慢。因此能用手写空格折叠解决的场景优先用--repifs正则分隔符更适合真正需要正则能力的复杂场景例如按多种空白字符混合切分。从源码实现看--ifs-regex的解析器pkg/cli/option_parse.go会调用lib.CompileMillerRegex把参数编译为正则对象存入options.ReaderOptions.IFSRegex--ips-regex同理存入IPSRegex。这与--ifs直接存入字符串字面量的路径不同也正是它更慢的原因所在。另外需要注意spaces、tabs、whitespace这些正则别名本身已经是正则表达式因此不应与--repifs搭配使用。事实上当提供了--ifs-regex时--repifs会被忽略。分隔符别名避免 shell 转义的烦恼许多分隔符在 shell 中需要转义例如--ifs ;、--ofs |。Miller 为此提供了命名别名可在命令行直接书写。执行以下命令查看完整列表mlr help list-separator-aliasesascii_esc \x1b ascii_etx \x03 ascii_fs \x1c ascii_gs \x1d ascii_null \x00 ascii_rs \x1e ascii_soh \x01 ascii_stx \x02 ascii_us \x1f asv_fs \x1f asv_rs \x1e colon : comma , cr \r crcr \r\r crlf \r\n crlfcrlf \r\n\r\n equals lf \n lflf \n\n newline \n pipe | semicolon ; slash / space tab \t usv_fs \xe2\x90\x9f usv_rs \xe2\x90\x9e这些别名中crlf、crlfcrlf、lflf等对换行风格特别有用——例如--ors crlf可以输出 RFC-4180 风格的 CRLF 行尾。asv_fs/asv_rs对应 ASCII 单位分隔符/记录分隔符与usv_fs/usv_rs对应 Unicode U241F/U241E则是 ASV/USV 这类专门用于分隔字段/记录的控制字符格式见 CSV/TSV/ASV/USV 等格式说明。而--ifs-regex与--ips-regex则另有正则别名表mlr help list-separator-regex-aliasesspaces ( ) tabs (\t) whitespace ([ \t])从源码 pkg/cli/separators.go 看这些别名都定义在SEPARATOR_NAMES_TO_VALUES与SEPARATOR_REGEX_NAMES_TO_VALUES两张映射表中pkg/cli/mlrcli_util.go 中的SeparatorFromArg与SeparatorRegexFromArg函数负责把别名解析为真实的分隔符字符串——如果命中别名表就返回对应值否则原样返回参数本身。这也是 shell 补全pkg/cli/flag_types.go 中的FlagValueCandidates能够为--ifs等 flag 枚举候选值的基础。命令行 flag 汇总综合以上内容Miller 的分隔符相关 flag 全景如下--rs --irs --ors --fs --ifs --ofs --repifs --ifs-regex --ps --ips --ops --ips-regex其中--rs {string}/--irs {string}/--ors {string}记录分隔符输入和输出 / 仅输入 / 仅输出--fs {string}/--ifs {string}/--ofs {string}字段分隔符输入和输出 / 仅输入 / 仅输出--ps {string}/--ips {string}/--ops {string}键值对分隔符输入和输出 / 仅输入 / 仅输出--repifs允许输入字段分隔符连续重复出现并只算一次--ifs-regex {string}/--ips-regex {string}以正则表达式形式指定输入字段分隔符 / 输入键值对分隔符。完整的 flag 说明可参见 reference-main-flag-list.md 的分隔符 flag 一节或在终端运行mlr help separator-flags查看。DSL 内置变量IRS、ORS、IFS、OFS、IPS、OPSMiller 在 DSL 中向用户暴露了只读的 内置变量IRS、ORS、IFS、OFS、IPS、OPS。与 AWK 不同你不能在 begin 块中给这些变量赋值——它们的值只反映你在命令行指定的内容因此用途有限主要用于调试或在put/filter中读取当前生效的分隔符。例如下面的命令在每条记录上追加一个字段d其值由输入字段分隔符,与输出字段分隔符;拼接而成mlr --ifs , --ofs ; --ips --ops : --from docs/src/data/a.dkvp put $d . IFS . ||| . OFS . a:1;b:2;c:3;d:,|||; a:4;b:5;c:6;d:,|||;可以看到d字段中嵌入了IFS,与OFS;的真实值直观验证了内置变量的含义。哪些分隔符适用于哪些文件格式不同文件格式对 RS/FS/PS 的支持程度差异很大。官方文档给出了完整的对照表RSFSPSCSV默认\n可设为\r\n*默认,必须是单字符无TSV默认\n可设为\r\n*默认\t必须是单字符无CSV-lite默认\n*默认,无TSV-lite默认\n*默认\t无JSON不适用记录位于{与}之间恒为,不可修改恒为:不可修改YAML不适用文档由---或单个数组分隔不适用不可修改恒为:不可修改DCF不适用段落由空行分隔不适用不可修改恒为:不可修改recutils不适用记录由空行分隔不适用不可修改恒为:不可修改DKVP默认\n默认,默认DKVPX默认\n默认,输入必须是单字符默认输入必须是单字符NIDX默认\n默认空格无XTAB不使用记录之间用额外的 FS 分隔\n*默认空格并允许重复PPRINT默认\n*空格并允许重复无Markdown恒为\n不可修改 *一个或多个空格加|再加一个或多个空格不可修改无* 在 Windows 上为\r\n。配套的注意事项如下CSVIRS必须是换行符输入时接受 CR/LF 行尾ORS必须是换行符默认或回车换行——例如--ors crlf或--ors \r\n用于在任何平台上输出 RFC-4180 风格行尾IFS必须是单字符。CSV-lite 没有这些限制。TSVIRS必须是换行符输入时接受 CR/LF 行尾ORS必须是换行符默认或回车换行IFS必须是制表符。TSV-lite 没有这些限制。JSON 与 YAML忽略命令行传入的分隔符 flag。无表头 CSV与使用逗号作为IFS的 NIDX 格式有相当程度的重叠详见 CSV 带表头与不带表头。XTAB的记录分隔符是字段分隔符的重复例如一条记录是x1,y2、下一条是x3,y4且OFS为换行符时输出行依次为x 1、y 2、一个额外换行、x 3、y 4。这意味着要定制 XTAB应设置OFS而非ORS。这张表的底层依据同样可以在 pkg/cli/separators.go 中找到defaultFSes、defaultPSes、defaultRSes三张表按格式csv、tsv、csvlite、tsvlite、json、yaml、dkvp、dkvpx、nidx、xtab、pprint、markdown等记录了每种格式的默认分隔符凡标记为N/A的即表示该格式不可参数化。例如defaultFSes[json] N/A、defaultRSes[xtab] \n\nXTAB 用两个换行——即空行——分隔记录与文档表格完全吻合。小结与实战建议Miller 的分隔符体系可以概括为三句话三层分隔记录分隔符RS切记录、字段分隔符FS切字段、键值对分隔符PS切键值三者分别有输入I与输出O两个版本共六个独立可配置项。按需取舍DKVP、XTAB 等格式三类分隔符齐全且全部可编程CSV/TSV 无键值对分隔符但字段分隔符可编程JSON/YAML/DCF/recutils 等格式的分隔符由规范决定不可修改。用对工具普通场景直接用--ifs/--ofs/--ips/--ops或快捷的--fs/--ps连续空格数据用--ifs space --repifs比正则快约 3 倍真正需要正则切分时用--ifs-regex/--ips-regex需要跨平台稳定行尾时用--ors crlf等别名。掌握这些参数你就可以在 CSV、TSV、DKVP、NIDX、XTAB、JSON 等格式之间自由转换数据也可以在同一格式内部按需定制分隔符——这正是 Miller 作为面向命名索引数据的 awk/sed/cut/join/sort的核心能力之一。赞分享CLI数据分析【免费下载链接】millerMiller is like awk, sed, cut, join, and sort for name-indexed data such as CSV, TSV, and tabular JSON项目地址https://gitcode.com/gh_mirrors/mi/miller点击查看免费下载相关推荐antd Space 分隔符separator完全指南相邻组件间隔符的配置方式与渲染原理antd Space 分隔符separator完全指南相邻组件间隔符的配置方式与渲染原理 Ant Design 的 Space https://link.前端UI组件设计系统StarRocks split 函数完全指南字符串按分隔符切分与 ARRAY 化处理StarRocks split 函数完全指南字符串按分隔符切分与 ARRAY 化处理 split 是 StarRocks 提供的字符串处理函数用于将一段字符数据库OLAP数据仓库大数据湖仓一体数据分析SeaTunnel Split Transform 详解按分隔符拆分字段的配置、行为与源码原理SeaTunnel Split Transform 详解按分隔符拆分字段的配置、行为与源码原理 Split Transform 是 SeaTunnel se数据集成ETL大数据批处理流处理变更数据捕获上一篇如何用Mousecape打造专属桌面体验5步个性化指南下一篇Zeus IoT解锁百万级设备并发的工业级物联网平台创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表