百万行CSV当数据库查:xsv正则搜索一条命令锁定目标行
百万行CSV当数据库查:xsv正则搜索一条命令锁定目标行
【免费下载链接】xsvA fast CSV command line toolkit written in Rust.项目地址: https://gitcode.com/gh_mirrors/xs/xsv
客服排障时拿到一张 2GB 的订单 CSV,只想要某客户的 3 条记录。用 Excel 打开,先等死机一轮;写 Python 脚本解析,又得先回忆 csv 模块怎么写。xsv 把这条路走得更直:xsv search直接把文件当数据库查,对每行跑一遍正则,命中就吐出来,不命中就跳过。百万行文件全程流式读,内存占用几乎不随文件变大。
一条命令筛出目标行
先看 5 行产品数据,后文所有命令都基于这份products.csv:
id,name,category,price,stock 1,笔记本电脑,电子产品,4999,15 2,机械键盘,电子产品,399,42 3,无线鼠标,电子产品,129,88 4,商务背包,箱包,299,36 5,办公椅,家具,899,12正则可以作用于任意一个字段,命中任意一格就算整行命中:
xsv search "电子" products.csv输出:
id,name,category,price,stock 1,笔记本电脑,电子产品,4999,15 2,机械键盘,电子产品,399,42 3,无线鼠标,电子产品,129,88三行电子产品全被捞出来,表头自动保留在结果里。参数不多,上手就这一条。
-s 锁定列的正确姿势
上面的"电子"其实全部命中的都是 category 列。但如果数据里 name 列偶尔也出现"电子"两个字(比如"电子秤"),全表搜就会混进噪音行。-s的作用就是告诉 xsv:只在这几列里跑正则,其他列一律不看。
xsv search -s category "电子" products.csv对比一下:
# 全表 5 列都参与匹配 xsv search "电子" products.csv # 只看 category 一列,其余列不参与匹配 xsv search -s category "电子" products.csv这条样本里两种写法结果一样,但逻辑差异在大数据上才显形:匹配范围从 5 列缩到 1 列,每行要跑的字段检查少 80%,列少了还能顺带躲开误命中。-s的列名语法(名称、1-based 序号、1-3范围、!取反)由 src/select.rs 统一解析,和xsv select通用。
正则、管道与组合参数
search接的是完整正则,不是普通字符串。几个参数各解决一个问题:
-i忽略大小写:用户搜的关键词全是大写,库里存的是小写,不加它就白搜。等价于给正则前面拼个(?i):
xsv search -i "KEYBOARD" products.csv-v反向匹配:平时筛"命中",排障时经常要筛"不命中"。排除全部电子产品,一行搞定:
xsv search -v -s category "电子" products.csv剩下两行是商务背包和办公椅。
正则特殊字符别裸奔:.在正则里匹配任意字符,真想匹配句点就写\.。同理* + ?也要转义,否则会按元字符语义去解释。
最后一个实用组合拳:搜出来只是第一步,往往还要挑列、排序。xsv 的命令之间靠标准管道串起来,search 负责筛行,select 负责挑列,sort 负责排序:
xsv search "电子" products.csv | xsv select name,price | xsv sort -N -s price按价格排序的电子产品清单直接出来。注意-N是数值排序,不加的话 4999 会排在 129 前面——字典序嘛。
大文件搜索的踩坑记录
📌 下面几条都是"现象 → 原因 → 正确姿势",按顺序看就行。
无表头文件少-n,首行静默丢失。现象:第一条数据不见了。原因:xsv 默认把首行当表头,既不参与搜索也不会写进结果。正确姿势:-n声明没有表头,列选择只能用 1-based 序号,不能用列名:
xsv search -n -s 2 "电子" products_no_header.csv用-s 列名搜无表头文件,直接报错。原因同上,没有表头就没有列名可查。正确姿势:换成序号-s 2。列的解析与选择逻辑见 src/select.rs。
管道里数字列排序结果"不对"。现象:price 列出来是 129、299、399、4999、899。原因:sort 默认按字符串字典序比。正确姿势:加-N按数值比,xsv sort -N -s price。
结果列太多,下游脚本读着费劲。search 即使只命中-s指定的列,输出的也是整行(这是 src/cmd/search.rs 里的既定行为)。要瘦列就接一段xsv select,别在下游再做字符串切割。
处理 GB 级文件时还有两条提速经验:正则范围能收窄就收窄,比如只查某一类邮箱就-s email "@example\.com",别让模式在整个宽表里乱撞;结果要落盘的话用内置的-o参数,语义明确,比 shell 重定向少一层意外:
xsv search -s price "1[0-9][0-9]$|5[0-9][0-9]$" products.csv -o midprice.csv参数速查表收个尾:
| 参数 | 作用 | 典型用法 |
|---|---|---|
| 正则表达式 | 必填,命中任意选中列的字段即输出整行 | "^1[0-9][0-9]$" |
-s | 限定搜索列,支持列名/序号/范围 | -s category |
-i | 忽略大小写,等价(?i)前缀 | -i "KEYBOARD" |
-v | 反向匹配,只输出不命中的行 | -v "测试" |
-o | 结果写文件而非标准输出 | -o result.csv |
-n | 首行不是表头,列选择只能用序号 | -n -s 2 |
不想背的话,xsv --help和xsv search --help里有全部说明;各命令的吞吐数据可以看仓库里的 BENCHMARKS.md,更多用法翻 README.md 即可。
如果搜出来的行还需要去重、统计或改格式,xsv 里还有 dedupe、stats、fmt 等命令可以接在管道后面,欢迎在评论区贴你的组合玩法。
【免费下载链接】xsvA fast CSV command line toolkit written in Rust.项目地址: https://gitcode.com/gh_mirrors/xs/xsv
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考