q是一个可以对文本文件执行SQL查询指令的命令行工具。q使用python编写,可以到q的官网下载安装。q的SQL是以SQLite为基础的,所以SQLite中的语法、函数,在q中都可以使用。

下面我们看下如何使用q。这里有一个样本文件,使用程序随机生成,共1000条数据,包含4个字段,分别表示日期时间、省份名称、订单号、金额,字段之间使用制表符分隔:

$ head text_data_analysis_example.log
2015-01-25 04:58:59     湖北    24161010220097026928    603.43
2015-01-17 13:43:06     山东    42422402656113053824    327.95
2015-01-12 08:15:58     江苏    64951386600336086457    647.55
2015-01-15 16:52:24     贵州    36495639647086452073    119.20
2015-01-05 18:17:36     山东    47026818054162399542    748.17
2015-01-15 09:58:27     西藏    25299664796208617721    446.77
2015-01-02 16:36:39     陕西    34143609866131614136    361.25
2015-01-17 19:10:56     湖南    53725682546965026178    896.24
2015-01-09 20:45:35     广西    20243175880019192418    261.06
2015-01-02 03:07:32     四川    22020296247794080625    148.12

例1:统计订单最多的10个省份名称以及订单数量:

$ q -d $'\t' "select c2,count(*) as count from ./text_data_analysis_example.log group by c2 order by count desc limit 10"
湖北    41
陕西    40
云南    38
山西    38
贵州    38
青海    37
安徽    35
福建    35
四川    34
重庆    34

说明:

  • 参数-d $'\t'设置字段分隔符为制表符;
  • c1表示第1个字段,c2表示第2个字段,以此类推;

例2:查询金额小于600的订单,按照金额从大到小排列,取前10条数据:

$ q -d $'\t' -f "3=%d" "select * from ./text_data_analysis_example.log where c4 < 600 order by c4 desc limit 10"
2015-01-05 22:45:50     江苏    98436513440879935488    599.02
2015-01-18 04:32:51     北京    46217457528636792832    599.01
2015-01-15 03:23:12     陕西    43877530968118345728    596.58
2015-01-25 09:05:14     安徽    65644845569971331072    596.54
2015-01-20 04:15:04     云南    67631199068351496192    596.38
2015-01-31 07:02:33     江西    94210643677476290560    595.93
2015-01-09 04:40:55     安徽    13315552512198803456    595.73
2015-01-17 09:05:31     贵州    77673355406810071040    595.72
2015-01-16 12:44:03     新疆    82040984345137070080    595.08
2015-01-24 06:20:18     湖南    21188659531566379008    594.71

说明:

  • 如果一个字段是数字,且比较大,q默认会以指数表示法显示,例如第1条数据的第3个字段默认会显示成“2.45264045363e+19”,为了按照原样显示数字,加上了-f "3=%d"这个参数,3表示第3个字段;
  • 如果不需要进行数字大小比较,可以使用--as-text参数,让所有字段都按照文本对待;

例3:输出所有订单的金额合计和金额平均值

$ q -d $'\t' "select sum(c4), avg(c4) from ./text_data_analysis_example.log"
487989.51       487.98951

说明:

  • sum、avg是SQLite的函数,查询所有可用函数,可以参考SQLite的文档

例4:和其他命令行工具配合使用

$ head text_data_analysis_example.log | q -d $'\t' -D "," "select c1, c2 from - "
2015-01-25 04:58:59,湖北
2015-01-17 13:43:06,山东
2015-01-12 08:15:58,江苏
2015-01-15 16:52:24,贵州
2015-01-05 18:17:36,山东
2015-01-15 09:58:27,西藏
2015-01-02 16:36:39,陕西
2015-01-17 19:10:56,湖南
2015-01-09 20:45:35,广西
2015-01-02 03:07:32,四川

说明:

  • head命令输出文件的前10行,然后传给q处理;
  • select ... from - 表示让q通过stdin读取数据,而不是文件,这样可以方便的配合其他工具处理数据;
  • 参数-D ","表示将输出数据的字段分隔符设置成逗号;

相关资源

可以使用--help获取q的帮助信息,更多内容,可以参考q和SQLite的网站: