csvq 1.18.1 常用 CLI 命令与工具详解

csvq v1.18.1 全部常用命令实测详解:单次查询/导出 flag、交互壳内置命令(ECHO/PRINT/SHOW/SOURCE/RELOAD CONFIG/$外部命令)、事务与文件回写(UPDATE/REPLACE USING/CREATE TABLE AS/ALTER)、游标/预处理/CTE/VIEW/UDF/流程控制、calc/fields/syntax/check-update 子命令与返回码语义

csvqcsvqSQLCLI工具Go命令行2026/11/03

csvq 1.18.1 常用 CLI 命令与工具详解

目标:把 csvq 的命令行用法、交互壳内置命令、事务性文件回写、SQL 编程特性与四个内置子命令逐一实测讲透,全部回显来自 Ubuntu 22.04 + csvq v1.18.1 的真实执行记录。环境搭建见 《Ubuntu 22.04 安装 csvq 1.18.1 指南》,参数含义见 《csvq 1.18.1 配置参数详解》。

一、环境信息

  • 操作系统:Ubuntu 22.04 LTS(jammy),x86_64;csvq v1.18.1(csvq version 1.18.1)
  • 工作目录:/root/csvdemo(账号 root)
  • 测试数据:users.csv(id,name,age,city,salary,joined 六列 5 行)、scores.tsv、products.json、access.ltsv、orders.jsonl、nested.json、fixdata.txt、sjis.csv
  • 交互壳回显约定:默认提示符为「当前目录 + >」;存在未提交事务时自动追加 (Uncommitted:N);查询结果固定以框线表格渲染

二、前置条件

  • csvq 已安装并在 PATH;/root/csvdemo 下已放置上述数据文件(users.csv 内容见选型篇 5.2)。
  • 表名含扩展名(带 .)时必须反引号包裹,否则报 syntax error: unexpected token "."(实测;交互壳内可省略 .csv 后缀直接用 users)。

三、命令总览

类别命令/用法说明
单次查询csvq [-f 格式] [-o 文件] "SELECT ..."非交互执行,flag 必须在语句前
脚本执行csvq -s script.sql顺序执行文件中的多条语句
交互壳csvq(无参)TTY 专用,支持事务/游标/UDF/内置命令
内置命令ECHO/PRINT/PRINTF/PWD/SOURCE/RELOAD CONFIG/$命令交互壳专用
自省SHOW FLAGS/ENV/RUNINFO/TABLES/FIELDS/CURSORS/FUNCTIONS查看状态
事务COMMIT/ROLLBACK首条写语句隐式开启事务(BEGIN 非法,见 5.1)
子命令calc/fields/syntax/check-update独立工具能力

四、查询与分析命令

4.1 基础查询与条件过滤

$ csvq "SELECT id, name, city FROM \`users.csv\` WHERE age > 30 ORDER BY salary DESC LIMIT 3"
id,name,city
3,Mildred,Nagoya
1,Louis,Tokyo
4,Harold,Fukuoka

4.2 聚合与分组

$ csvq "SELECT u.city, COUNT(*) AS n, AVG(u.age) AS avg_age FROM \`users.csv\` u GROUP BY u.city ORDER BY n DESC"
city,n,avg_age
Tokyo,1,35
Osaka,1,28
Nagoya,1,42
Fukuoka,1,31
Sapporo,1,26

4.3 跨文件 JOIN(含 TSV/JSON)

$ csvq "SELECT u.name, s.subject, s.score FROM \`users.csv\` u INNER JOIN \`scores.tsv\` s ON u.id = s.user_id WHERE s.score >= 90"
name,subject,score
Louis,math,92
Mildred,english,95
Sophie,science,99

4.4 子查询与 CTE

$ csvq "SELECT name, salary FROM \`users.csv\` WHERE salary > (SELECT AVG(salary) FROM \`users.csv\`)"
name,salary
Louis,5200000
Mildred,6300000

CTE 实测(交互壳内单行):

/root/csvdemo > WITH t AS (SELECT city, AVG(salary) AS avg_sal FROM users GROUP BY city) SELECT * FROM t ORDER BY avg_sal DESC;
+----------+---------+
|   city   | avg_sal |
+----------+---------+
| Nagoya   | 6300000 |
| Tokyo    | 5200000 |
| Osaka    | 4100000 |
| Fukuoka  | 3800000 |
| Sapporo  | 3500000 |
+----------+---------+

4.5 窗口函数

$ csvq "SELECT name, city, salary, RANK() OVER (PARTITION BY city ORDER BY salary DESC) AS rk FROM \`users.csv\` LIMIT 3"
name,city,salary,rk
Mildred,Nagoya,6300000,1
Louis,Tokyo,5200000,1
Sean,Osaka,4100000,1

4.6 定长/编码/嵌套 JSON 读取

$ csvq -i FIXED -m '[10,18,25]' "SELECT * FROM \`fixdata.txt\`"
name,city,salary
Louis,Tokyo,5200000
Sean,Osaka,4100000
Mildred,Nagoya,6300000
$ csvq -e SJIS "SELECT * FROM \`sjis.csv\`"
名前,太郎,東京
花子,二郎,大阪
$ csvq -j 'users' "SELECT * FROM \`nested.json\`"
name,tags
Tom,"[""x"",""y""]"
Amy,"[""z""]"

要点:FIXED 的 -m 是累积切割位不是列宽;SJIS 在 AUTO 下也能识别;嵌套对象数组用 -j 指定查询路径(users 与 users{} 实测等价)。

五、文件读写命令(直接改磁盘文件)

⚠️ 警告:csvq 的写语句直接修改源文件。交互壳内有事务缓冲(COMMIT 前不落盘、ROLLBACK 可还原),但非交互单条语句自动提交、无回滚机会——生产文件先 cp 备份再操作。

5.1 UPDATE 与 ROLLBACK(交互壳实测)

/root/csvdemo > UPDATE users SET name = 'Mildred-X' WHERE id = 3;
1 record updated on "/root/csvdemo/users.csv".
/root/csvdemo (Uncommitted:1) > ROLLBACK;
Rollback: file "/root/csvdemo/users.csv" is restored.

提示符出现 (Uncommitted:1) 即表示有 1 个文件的改动未落盘;此时 SELECT 读到的是改后值,ROLLBACK 后恢复原值(实测还原为 Mildred)。

⚠️ 注意:csvq 没有 BEGIN 语句——实测交互壳执行 BEGIN; 报 [L:1 C:1] syntax error: unexpected token "BEGIN"。事务由首条写语句(UPDATE/INSERT/REPLACE/DELETE/CREATE/ALTER)隐式开启,COMMIT/ROLLBACK 结束;ROLLBACK 后实测文件逐字节还原:

/root/csvdemo > BEGIN;
[L:1 C:1] syntax error: unexpected token "BEGIN"
/root/csvdemo > UPDATE users SET name = 'TmpX' WHERE id = 1;
1 record updated on "/root/csvdemo/users.csv".
/root/csvdemo (Uncommitted:1) > ROLLBACK;
Rollback: file "/root/csvdemo/users.csv" is restored.
/root/csvdemo > SELECT id, name FROM users WHERE id = 1;
+----+--------+
| id |  name  |
+----+--------+
| 1  | Louis  |
+----+--------+

5.2 INSERT / DELETE / COMMIT

/root/csvdemo > INSERT INTO users (id, name, age, city, salary, joined) VALUES (6, 'Taro', 40, 'Kyoto', 4500000, '2023-01-10');
1 record inserted on "/root/csvdemo/users.csv".
/root/csvdemo (Uncommitted:1) > COMMIT;
Commit: file "/root/csvdemo/users.csv" is updated.
/root/csvdemo > DELETE FROM users WHERE id = 6;
1 record deleted on "/root/csvdemo/users.csv".
/root/csvdemo (Uncommitted:1) > COMMIT;
Commit: file "/root/csvdemo/users.csv" is updated.

5.3 REPLACE INTO:必须带 USING 键

普通 REPLACE INTO ... VALUES 实测语法错误——csvq 的 REPLACE 是"按键替换"语法,必须 USING (键列):

/root/csvdemo > REPLACE INTO users (id, name, age, city, salary, joined) VALUES (6, 'Jiro', 44, 'Kobe', 4800000, '2023-02-01');
[L:1 C:58] syntax error: unexpected token "VALUES"
/root/csvdemo > REPLACE INTO users (id, name, age, city, salary, joined) USING (id) VALUES (2, 'Sean-B', 28, 'Osaka', 4300000, '2020-10-15');
1 record replaced on "/root/csvdemo/users.csv".

5.4 CREATE TABLE AS:新文件落盘

/root/csvdemo > CREATE TABLE `backup.csv` AS SELECT id, name FROM users WHERE age > 30;
file "/root/csvdemo/backup.csv" is created.
/root/csvdemo (Uncommitted:1) > COMMIT;
Commit: file "/root/csvdemo/backup.csv" is created.

目标文件名同样受"带点必须反引号"约束:不写反引号报 [L:1 C:20] syntax error: unexpected token "."(实测)。

5.5 ALTER TABLE:加列与改属性

加列的正确语法是 ADD (列名),MySQL 式 ADD COLUMN 列名 实测报错:

/root/csvdemo > ALTER TABLE users ADD COLUMN dept;
[L:1 C:30] syntax error: unexpected token "dept"
/root/csvdemo > ALTER TABLE users ADD (dept);
1 field added on "/root/csvdemo/users.csv".
/root/csvdemo (Uncommitted:1) > COMMIT;
Commit: file "/root/csvdemo/users.csv" is updated.
/root/csvdemo > $head -1 /root/csvdemo/users.csv
id,name,age,city,salary,joined,dept

改文件属性用 SET <属性> TO <值>。大坑实测:ALTER TABLE users SET DELIMITER TO ';'; COMMIT 后文件内容确实按分号重写($head -1 看到 id;name;...),但读侧元数据仍显示 Delimiter: ',',整行退化为单列(Fields: 1. id;name;age;...)——分隔符变更必须配合重新加载/显式 -d ';' 查询,改前务必备份。

六、格式转换命令(-f + -o)

csvq 是顺手的平面文件格式转换器,实测三组:

$ csvq -f JSON -o /root/csvdemo/b2/out_users.json "SELECT id, name, salary FROM \`users.csv\` WHERE age > 30"
$ cat /root/csvdemo/b2/out_users.json
[{"id":"1","name":"Louis","salary":"5200000"},{"id":"3","name":"Mildred","salary":"6300000"},{"id":"4","name":"Harold","salary":"3800000"}]
$ csvq -f CSV "SELECT * FROM \`products.json\`"
sku,name,price
A-100,keyboard,4980
A-200,mouse,1980
B-100,monitor,28900
B-200,headset,7800
$ csvq -f TSV "SELECT time, host, status FROM \`access.ltsv\`"
time	host	status
2026-11-01T081203+0900	web01	200
2026-11-01T081205+0900	web01	500

要点:-o 导出与管道输出默认格式不同(CSV for pipe / TEXT otherwise);LTSV 值含冒号会被吞(08:12:03 → 081203,见 9.3);-N 去表头、-D '|' 换输出分隔符、-E SJIS 换输出编码均实测可用。

七、交互壳内置命令

7.1 输出与外部命令

/root/csvdemo > ECHO 'csvq echo test';
csvq echo test
/root/csvdemo > PRINT 1 + 2;
3
/root/csvdemo > PRINTF '%s -> %d' USING 'abc', 42;
abc -> 42
/root/csvdemo > PWD;
/root/csvdemo
/root/csvdemo > $echo 'external command';
external command

$ 前缀直接调系统命令(实测 $ls、$head、$sed 均可用),是壳内核实现场的第一工具。

7.2 自省命令

/root/csvdemo > SHOW FLAGS;          # 30 个 flag 现值(全表见配置篇)
/root/csvdemo > SHOW ENV;            # 宿主环境变量映射(@%PWD/@%HOME/@%PATH...)
/root/csvdemo > SHOW RUNINFO;        # @#UNCOMMITTED/@#VERSION/@#WORKING_DIRECTORY 等
/root/csvdemo > SHOW TABLES;
No table is loaded
/root/csvdemo > SHOW FIELDS FROM users;

                   Fields in users
-----------------------------------------------------
 Type: File
 Path: /root/csvdemo/users.csv
 Format: CSV     Delimiter: ','   Enclose All: false
 Encoding: UTF8  LineBreak: LF    Header: true
 Status: Fixed
 Fields:
   1. id
   2. name
   3. age
   4. city
   5. salary
   6. joined
/root/csvdemo > SHOW CURSORS;
No cursor is declared
/root/csvdemo > SHOW FUNCTIONS;

 Scalar Functions
------------------
 add_tax (@p)

7.3 脚本与配置加载

/root/csvdemo > SOURCE '/hostshare/stmts.sql';
+-----+----------+
| seq |   name   |
+-----+----------+
|   1 | Louis    |
...
/root/csvdemo > RELOAD CONFIG;

SOURCE 实测需带引号的绝对路径(裸文件名 SOURCE stmts.sql; 报 unexpected token ";");RELOAD CONFIG; 热加载 csvq_env.json(实测提示符实时变化)。

7.4 变量:@%(环境/会话)与 @#(运行时只读)

/root/csvdemo > SET @%MYVAR TO 'demo-value';
/root/csvdemo > ECHO @%MYVAR;
demo-value
/root/csvdemo > UNSET @%MYVAR;
/root/csvdemo > ECHO @#VERSION;
1.18.1

SQL 会话变量用 VAR(见 8.2),与 @% 环境变量是两套体系。

八、SQL 编程特性(交互壳)

8.1 游标:标识符不带 @,先 VAR 声明目标变量

/root/csvdemo > DECLARE c1 CURSOR FOR SELECT name FROM users WHERE age > 30;
/root/csvdemo > OPEN c1;
/root/csvdemo > VAR @n1;
/root/csvdemo > FETCH c1 INTO @n1;
/root/csvdemo > ECHO @n1;
Louis
/root/csvdemo > FETCH c1 INTO @n1;
/root/csvdemo > ECHO @n1;
Mildred
/root/csvdemo > CLOSE c1;
/root/csvdemo > DISPOSE CURSOR c1;

实测坑:FETCH ... INTO @n1 在变量未声明时报 variable @n1 is undeclared——必须先 VAR @n1;;游标名写 @c 形式直接语法错(DECLARE @c CURSOR 报 unexpected token "CURSOR");WHILE VAR ... IN c2 前忘记 OPEN 报 cursor c2 is closed。

8.2 会话变量与 SELECT INTO

/root/csvdemo > VAR @mx;
/root/csvdemo > SELECT MAX(salary) INTO @mx FROM users;
/root/csvdemo > ECHO @mx;
6300000
/root/csvdemo > VAR @id := 0;
/root/csvdemo > SELECT @id := @id + 1 AS seq, name FROM users;
+-----+----------+
| seq |   name   |
+-----+----------+
|   1 | Louis    |
|   2 | Sean     |
...

8.3 预处理语句

/root/csvdemo > PREPARE p1 FROM 'SELECT name, city FROM users WHERE id = ?;';
/root/csvdemo > EXECUTE p1 USING 2;
+------+--------+
| name |  city  |
+------+--------+
| Sean | Osaka  |
+------+--------+
/root/csvdemo > DISPOSE PREPARE p1;

8.4 VIEW 临时表

/root/csvdemo > DECLARE v1 VIEW AS SELECT id, name FROM users WHERE age < 30;
/root/csvdemo > SELECT * FROM v1;
+----+--------+
| id |  name  |
+----+--------+
| 2  | Sean   |
| 5  | Sophie |
+----+--------+
/root/csvdemo > DISPOSE VIEW v1;

8.5 用户自定义函数:参数不能带类型

/root/csvdemo > DECLARE add_tax FUNCTION (@p) AS BEGIN RETURN @p * 1.1; END;
/root/csvdemo > SELECT name, add_tax(salary) AS with_tax FROM users LIMIT 2;
+--------+----------+
|  name  | with_tax |
+--------+----------+
| Louis  |  5720000 |
| Sean   |  4510000 |
+--------+----------+

实测两处语法禁区:参数表写类型 (@p INT) 报 unexpected token "INT";函数体内 RETURN CAST(@p * 1.1 AS INT); 报 unexpected token "AS"。

8.6 流程控制:IF / WHILE 必须单行

/root/csvdemo > IF (SELECT COUNT(*) FROM users) > 4 THEN ECHO 'more than 4 users'; ELSE ECHO 'few users'; END IF;
more than 4 users
/root/csvdemo > VAR @i := 0;
/root/csvdemo > WHILE @i < 3 DO ECHO @i; SELECT @i := @i + 1; END WHILE;
0
+--------------+
| @i := @i + 1 |
+--------------+
|            1 |
+--------------+
1
...

跨行书写实测失败:WHILE @i < 3 换行报 unexpected termination(v1.18.1 的 continuous_prompt 不触发续读)。

九、子命令工具与返回码

9.1 csvq fields:查看文件字段

$ csvq fields users.csv
id
name
age
city
salary
joined

9.2 csvq calc:管道单值计算

用法为"stdin 提供数据(列名 c1),参数给表达式":

$ echo 'foo' | csvq calc "base64_encode(c1)"
Zm9v
$ echo 123 | csvq calc "c1 + 100"
223

无 stdin 时报 incorrect usage: STDIN is empty;表达式必须作为恰好 1 个参数传入。

9.3 csvq syntax:打印 SQL 语法

$ csvq syntax select | head -8

                             Search: select
-------------------------------------------------------------------------
 SELECT Statement
     select_query
         : [<with_clause>] <select_entity> [<order_by_clause>]
           [<limit_clause>] [FOR UPDATE]

排障利器:不确定语法时直接查官方文法(如 csvq syntax "replace into" 可看到 USING 子句)。

9.4 csvq check-update:版本检查

$ csvq check-update
The current version 1.18.1 is up to date.
$ echo $?
0

9.5 返回码语义(实测)

场景rc关键回显
正常0—
文件不存在16[L:1 C:15] file nosuchfile does not exist
语法错误4[L:1 C:9] syntax error: unexpected token "BOGUS"
触发显式错误64TRIGGER ERROR 'msg' → [L:1 C:1] manual
参数冲突2incorrect usage: no argument can be passed when "--source" option is specified
csvqrc 非法语句1/root/csvdemo/csvqrc [L:1 C:5] @@ROW_LIMIT is an unknown flag

十、常用操作速查

需求命令
查 CSVcsvq "SELECT * FROM \f.csv` LIMIT 10"`
查 TSV/JSON/JSONL/LTSV同上,按扩展名自动识别
查定长文件csvq -i FIXED -m '[10,18,25]' "SELECT * FROM \f.txt`"`
查 SJIS 文件csvq -e SJIS "SELECT * FROM \f.csv`"`(AUTO 亦可)
查嵌套 JSON 数组csvq -j 'users' "SELECT * FROM \f.json`"`
结果转 JSON 落盘csvq -f JSON -o out.json "SELECT ..."
结果转 TSV 到 stdoutcsvq -f TSV "SELECT ..." | ...
批量执行脚本csvq -s script.sql
改文件(可回滚)交互壳 UPDATE/INSERT/DELETE → COMMIT/ROLLBACK
按键替换整行REPLACE INTO t (...) USING (键) VALUES (...)
新表落盘CREATE TABLE \new.csv` AS SELECT ...`
加列ALTER TABLE t ADD (col)
看文件元数据SHOW FIELDS FROM t / csvq fields f.csv
看当前参数SHOW FLAGS;
查语法csvq syntax <关键字>
单值计算进管道echo x | csvq calc "expr(c1)"

十一、常见问题

11.1 表名带点就报 unexpected token "."

csvq 把 . 当语法元素,users.csv 这类文件名一律写 `users.csv`(实测交互壳内可省扩展名直接 users)。

11.2 交互壳脚本管道喂不进去

实测报 input from pipe or redirection cannot be used——交互壳坚持 TTY。批量执行请走 csvq -s,或逐条 csvq "语句"。

11.3 多行 SQL 报 unexpected termination

v1.18.1 交互壳不续读,单条语句必须一行写完;复杂逻辑落 .sql 文件用 SOURCE '/绝对路径'; 或 -s。

11.4 REPLACE INTO 报 unexpected token "VALUES"

csvq 的 REPLACE 必须 USING (键列) 指明匹配键(5.3 实测)。

11.5 改完 UPDATE 文件没变 / 想撤销

未 COMMIT 的改动只在内存缓冲(提示符 (Uncommitted:1)):COMMIT; 落盘、ROLLBACK; 还原(实测文件恢复原文)。非交互模式没有这层缓冲,语句成功即落盘。

11.6 LTSV 时间字段值缺冒号

LTSV 按首个冒号切 key/value,值内冒号被吞(实测 2026-11-01T08:12:03+09:00 导出成 2026-11-01T081203+0900)。含冒号值建议改按 TSV 导入后 SQL 处理。

11.7 找不到 --row-limit / 输出太多刷屏

csvq 无行数限制 flag(--row-limit 报 flag provided but not defined),SQL 里写 LIMIT n;导出场景配 -f CSV -o 文件。

十二、参考链接