q命令-用SQL分析文本文件

原创:打码日记(微信公众号ID:codelogs),欢迎分享,转载请保留出处。

在Linux上分析文本文件时,一般会使用到grep、sed、awk、sort、uniq等命令,但这些命令都有一定的学习成本,而如果是用SQL来分析数据的话,这对广大后端程序员来说,就要简单很多了。

而q命令就是这样一款工具,可以在空白、逗号分隔的文本文件上执行SQL运算,非常方便。

ubuntu下安装
$ sudo apt install python3-q-text-as-data

centos下可下载安装包安装
$ wget https://github.com/harelba/q/releases/download/v3.1.6/q-text-as-data-3.1.6.x86_64.rpm
$ rpm -Uvh q-text-as-data-3.1.6.x86_64.rpm

常见用法

默认情况下,q将文本文件中每一行当作一条数据,使用空白作为字段分隔符。
假设有如下学生列表,要查询出大于16岁的学生的id与姓名,如下:

$ cat students.txt
id name age sex
1 person1 15 0
2 person2 15 0
3 person3 16 0
4 person4 16 0
5 person5 16 0
6 person6 17 1
7 person7 17 1
8 person8 17 1
9 person9 18 1
10 person10 18 1

查询出大于16岁的学生的id与姓名
-H : 告知q命令第一行是标题行
$ q -H 'select id,name from students.txt where age>16'
6 person6
7 person7
8 person8
9 person9
10 person10

-O可使输出结果中带有标题
$ q -H -O 'select id,name from students.txt where age>16'
id name
6 person6
7 person7
8 person8
9 person9
10 person10

如果文件中没有标题行的话,可使用 c1、c2、c3...来引用字段,如下:

$ cat students.txt
1 person1 15 0
2 person2 15 0
3 person3 16 0
4 person4 16 0
5 person5 16 0
6 person6 17 1
7 person7 17 1
8 person8 17 1
9 person9 18 1
10 person10 18 1

查询出大于16岁的学生的id与姓名
$ q 'select c1,c2 from students.txt where c3>16'
6 person6
7 person7
8 person8
9 person9
10 person10

q命令也可直接从标准输入中读取数据,使用 -作为表名即可,如下:

$ cat students.txt | q -H -O 'select * from - limit 2'
id name age sex
1 person1 15 0
2 person2 15 0

q命令默认使用空白作为分隔符,但也可以通过 -d指定分隔符,这样可以很容易地分析csv文件(,分隔)或tsv文件(\t分隔),如下:

$ cat students.csv
id,name,age,sex
1,person1,15,0
2,person2,15,0
3,person3,16,0
4,person4,16,0
5,person5,16,0
6,person6,17,1
7,person7,17,1
8,person8,17,1
9,person9,18,1
10,person10,18,1

-d : 指定分隔符
$ q -H -d, 'select count(*) from students.csv where age>16'
5

q命令还可以自动识别文件中的双引号 ",这使得字段值中带有逗号的场景也可以很容易处理,如下:

$ cat students.csv
id,name,age,sex
1,"person,lisi",15,0
2,"person,wangwu",15,0
3,person3,16,0
4,person4,16,0
5,person5,16,0
6,person6,17,1
7,person7,17,1
8,person8,17,1
9,person9,18,1
10,person10,18,1

q命令可自动将引号内数据读取成一个字段
$ q -H -d, 'select * from students.csv where age=15'
1,"person,lisi",15,0
2,"person,wangwu",15,0

awk没有这种机制,字段引用错位,导致查不到数据
$ awk -F, '$3==15{print $0}' students.csv

q命令也可以很容易地处理最后一列带分隔符的场景,如下:

ps输出的最后一列COMMAND带有空格
$ ps 1
    PID TTY      STAT   TIME COMMAND
      1 ?        Ss     1:28 /sbin/init auto noprompt text

如果用awk,会发现漏掉了空格后的部分
$ ps 1 | awk '{print $5}'
COMMAND
/sbin/init

q命令可使用-c 5指定列数量,这样最后一列就完整查出来了
$ ps 1 | q -H -O -c 5 'select COMMAND from -'
COMMAND
"/sbin/init auto noprompt text"

多文件关联查询

SQL中最强大的关联查询,q命令也是可以支持的,如下:

$ cat user.txt
id name
1 zhangsan
2 lisi
3 wangwu
4 pangliu

$ cat score.txt
id score
1 86
2 57
3 92

$ q -H 'select u.id,u.name,s.score from user.txt u left join score.txt s on u.id=s.id'
1 zhangsan 86
2 lisi 57
3 wangwu 92
4 pangliu

q命令使用了SQLite这个嵌入式数据库,运行过程中,q命令会在SQLite中创建临时数据库与表,并将文本数据插入到临时表中,然后SQL语句直接执行在这个临时表上。

所以理论上,只要是SQLite支持的SQL语法,q命令也支持。

可以通过 -A查看临时表的表结构,如下:

仅查看表结构,SQL实际不会执行
$ q -H -d, -A 'select * from students.csv'
Table for file: students.csv
  id - int
  name - text
  age - int
  sex - int

可以发现, idagesex字段都是int类型,这是q命令自动从文本数据中分析出来的。

往期内容

Original: https://www.cnblogs.com/codelogs/p/16060830.html
Author: 扣钉日记
Title: q命令-用SQL分析文本文件

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/581373/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • IllegalArgumentException :argument type mismatch

    上周学习的 封装查询语句,今天在使用中查询语句的封装就发现了一个异常 java.Lang.IllegalArgumentException:argument type mismat…

    Java 2023年6月5日
    0102
  • Java 获取Word中的所有插入和删除修订

    在 Word 文档中启用跟踪更改功能后,会记录文档中的所有编辑行为,例如插入、删除、替换和格式更改。对插入或删除的内容,可通过本文中介绍的方法来获取。 引入Jar 方法1 手动引入…

    Java 2023年5月29日
    0131
  • java高级-续1

    IO 所谓IO就是输出输出(input/output)。一般的理解都是相对于计算机而言的输入输出。 比如: 输出设备:显示器,耳机,音响,打印机….. 输入设备:键盘,…

    Java 2023年6月7日
    0122
  • Wildfly8 更改response header中的Server参数

    项目经过局方安全检查需要屏蔽掉服务器中间件信息,查了一下午,网上看到的都是修改jboss7的,我们使用的wildfly8(jboss改名为wildfly),修改地方不一样,折磨了半…

    Java 2023年6月7日
    0119
  • 9、线程礼让yield

    线程礼让: 1、让正在执行的线程为暂停,但不阻塞; 2、让状态转为就绪 3、让cpu重写调度,礼让不一定成功; Thread.currentThread()获取当前线程的引用 Or…

    Java 2023年6月8日
    083
  • springboot+logback日志规范

    <!–?</code–><code class=”xml keyword”>xml</code> <code class=”xm…

    Java 2023年5月30日
    069
  • Spring(八):Bean的作用域

    Spring框架支持六个作用域,其中四个只有在Web中才能用到,在此我们只说明前两种作用域。 下面是所有的六种作用域: ScopeDescription (Default) Sco…

    Java 2023年6月15日
    084
  • Java线程池中线程的状态简介

    首先明确一下线程在JVM中的各个状态(JavaCore文件中) 1.死锁,Deadlock(重点关注) 2.执行中,Runnable(重点关注) 3.等待资源,Waiting on…

    Java 2023年6月15日
    084
  • 二、mybatis之数据输出

    上一篇我们做了一个入门案例,是我们做mybatis的基本步骤,不熟悉的可以回顾一下https://www.cnblogs.com/jasmine-e/p/15330355.html…

    Java 2023年6月16日
    085
  • git安装与使用,未完待续… …

    一、git概念 二、git简史 三、git的安装 四、git结构 五、代码托管中心—本地库和远程库的交互方式 六、初始化本地仓库 七、git常用命令 1、add和commit命令 …

    Java 2023年6月5日
    0111
  • SpringBoot中@RequestBody与@ResponseBody的作用

    前端使用json传值,将json数据封装到对应的vo对象中,后端将得到的vo对象传递到接口中进行查询。 需要注意的是,如果使用@RequestBody,那么必须使用post方式提交…

    Java 2023年5月30日
    077
  • suse11离线安装nginx

    安装gcc因为Nginx是C语言写的,所以在安装nginx前必须在你的系统上搭建好C环境。 查看是否已经安装gcc 如果查看到了版本信息,表示已经安装过了,可以直接安装nginx,…

    Java 2023年5月30日
    0120
  • java和spring 线程池总结

    线程的使用在java中占有极其重要的地位,在jdk1.4极其之前的jdk版本中,关于线程池的使用是极其简陋的。在jdk1.5之后这一情况有了很大的改观。Jdk1.5之后加入了jav…

    Java 2023年5月29日
    078
  • 2022-8-18 第六组 JDBC

    JDBC 1. 概念:Java DataBase Connectivity Java 数据库连接, Java语言操作数据库 JDBC本质:其实是官方(sun公司)定义的一套操作所有…

    Java 2023年6月13日
    064
  • [Java编程思想] 第六章 访问权限控制

    6.1 包:库单元 包内含有一组类,它们在单一的名字空间之下被组织在了一起。 当编写一个Java源代码文件时,此文件通常被称为编译单元。每个编译单元都必须有一个后缀名.java,而…

    Java 2023年6月5日
    083
  • Java系统性能优化实战读书笔记

    前言 我是个喜欢看电子书的人,因为可以边看边记笔记,写感言,对书中精彩的地方进行学习实践,非常感谢本书作者家智老师,分享了这本书的最新电子版,让我有机会能阅读本书! 本书正版链接:…

    Java 2023年5月29日
    0114
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球