我一直在寻找一种将 CSV 文件作为关系数据库表进行遍历的方法。
我做了一些研究,因为我发现没有任何东西完全符合我的要求。我发现了几个部分不错的选择,即:
- 术语SQL- 它接受 stdin 或一个文件并允许在其上执行一些 sql - 但只设置一个“表”
- csv2sqlite- 这是非常有前途的,因为它允许比 termsql 潜在更多的 sql 优点 - 但仍然只有一个“表”
- 这个 ULSE 问题- 描述了如何使用 unix 文件遍历命令实现集合操作 - 有希望和可能的起点
遍历并执行一些类似数据库的操作是可能的,而且非常简单单身的csv/文本文件(列总和、平均值、最小值、最大值、子集等),但不是两个文件,它们之间有一些联系。还可以将文件导入到临时数据库中进行查询,我已经这样做了,尽管没有我想要的那么实用。
长话短说- 我基本上想要一种方便的方法来对 csv 文件进行快速而肮脏的 sql 连接。不是在寻找成熟的基于文本的 RDBMS,而只是寻找一种更好的方法来对 csv RDBMS 提取进行一些分析。
例子:
sqlthingy -i tbl1.csv tbl2.csv -o 'select 1,2,3 from tbl1, tbl2 where tbl1.1 = tbl2.1'
这似乎是一个足够有趣的问题,我可以花一些时间来解决,但我想知道它是否已经存在。
答案1
答案2
你想要的是join
命令,这是由 POSIX 指定。
这是您的示例伪代码命令:
sqlthingy -i tbl1.csv tbl2.csv -o 'select 1,2,3 from tbl1, tbl2 where tbl1.1 = tbl2.1'
这是一个实际工作命令,使用join
等效命令:
join -t, tbl1.csv tbl2.csv
如果两个文件都只有两个字段(以逗号分隔),则此join
命令正是您在伪代码中表示的内容。
如果它们有更多字段,但您只想每个文件中的第二个字段,仍然加入第一个字段,您可以使用:
join -t, -o 0,1.2,2.2 tbl1.csv tbl2.csv
如果您想加入不同的领域,也有相应的标志。
它不是一个成熟的 RDBMS;而是一个成熟的 RDBMS。例如,您只能使用两个文件和一个连接字段。但对于你所要求的:
TL;DR - 我基本上想要一种方便的方法来对 csv 文件进行快速而肮脏的 sql 连接。不是在寻找成熟的基于文本的 RDBMS,而只是寻找一种更好的方法来对 csv RDBMS 提取进行一些分析。
它符合要求完美。
您还应该检查一下comm
,也由 POSIX 指定,用于打印两个文件共有的行(或仅存在于其中一个或另一个文件中,或类似的东西)。
另请注意,join
和都可以通过用作文件名来comm
对标准输入进行操作。-
如果您想要带有“group by”子句的 SQL“count()”命令的等效项,只需获取所需的列(它将join
使用连接字段进行排序,或者如果直接来自文件,您可以自己排序)并通过管道将其通过uniq -c
。
答案3
阿帕奇钻机可以直接查询 CSV 和 JSON 文件,并连接它们。
您只需第一次定义文件位置并根据文件扩展名调整设置(例如是否使用第一行作为标题)。
那么就好像您使用的是mysql
客户端,但表是磁盘上的实际文件
$ ./bin/drill-embedded
OpenJDK 64-Bit Server VM warning: ignoring option MaxPermSize=512M; support was removed in 8.0
Nov 07, 2017 7:05:52 PM org.glassfish.jersey.server.ApplicationHandler initialize
INFO: Initiating Jersey application, version Jersey: 2.8 2014-04-29 01:25:26...
apache drill 1.11.0
"drill baby drill"
0: jdbc:drill:zk=local> SELECT ix.field1, o.field2, o.field3
. . . . . . . . . . . > FROM dfs.myfolder.`file1.tsv` ix
. . . . . . . . . . . > LEFT JOIN dfs.myfolder.`file2.tsv` o ON (o.field=ix.field)
. . . . . . . . . . . > LIMIT 10;
+-------------+-------------+---------------+
| field1 | field2 | field3 |
+-------------+-------------+---------------+
...redacted...
+-------------+-------------+---------------+
10 rows selected (0.656 seconds)
0: jdbc:drill:zk=local>