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

如果是其它Linux發行版,可以參考官網安裝文件:http://harelba。github。io/q/#installation。

常見用法

分析空白分隔檔案

預設情況下,q將文字檔案中每一行當作一條資料,使用空白作為欄位分隔符。

假設有如下學生列表,要查詢出大於16歲的學生的id與姓名,如下:

$ cat students。txtid name age sex1 person1 15 02 person2 15 03 person3 16 04 person4 16 05 person5 16 06 person6 17 17 person7 17 18 person8 17 19 person9 18 110 person10 18 1# 查詢出大於16歲的學生的id與姓名# -H : 告知q命令第一行是標題行$ q -H ‘select id,name from students。txt where age>16’6 person67 person78 person89 person910 person10# -O可使輸出結果中帶有標題$ q -H -O ‘select id,name from students。txt where age>16’id name6 person67 person78 person89 person910 person10

如果檔案中沒有標題行的話,可使用

c1、c2、c3。。。

來引用欄位,如下:

$ cat students。txt1 person1 15 02 person2 15 03 person3 16 04 person4 16 05 person5 16 06 person6 17 17 person7 17 18 person8 17 19 person9 18 110 person10 18 1# 查詢出大於16歲的學生的id與姓名$ q ‘select c1,c2 from students。txt where c3>16’6 person67 person78 person89 person910 person10

從標準輸入讀取資料

q命令也可直接從標準輸入中讀取資料,使用

-

作為表名即可,如下:

$ cat students。txt | q -H -O ‘select * from - limit 2’id name age sex1 person1 15 02 person2 15 0

分析csv檔案

q命令預設使用空白作為分隔符,但也可以透過

-d

指定分隔符,這樣可以很容易地分析csv檔案(

分隔)或tsv檔案(

\t

分隔),如下:

$ cat students。csvid,name,age,sex1,person1,15,02,person2,15,03,person3,16,04,person4,16,05,person5,16,06,person6,17,17,person7,17,18,person8,17,19,person9,18,110,person10,18,1# -d : 指定分隔符$ q -H -d, ‘select count(*) from students。csv where age>16’5

q命令還可以自動識別檔案中的雙引號

,這使得欄位值中帶有逗號的場景也可以很容易處理,如下:

$ cat students。csvid,name,age,sex1,”person,lisi“,15,02,”person,wangwu“,15,03,person3,16,04,person4,16,05,person5,16,06,person6,17,17,person7,17,18,person8,17,19,person9,18,110,person10,18,1# q命令可自動將引號內資料讀取成一個欄位$ q -H -d, ‘select * from students。csv where age=15’1,”person,lisi“,15,02,”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。txtid name1 zhangsan2 lisi3 wangwu4 pangliu$ cat score。txtid score1 862 573 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 862 lisi 573 wangwu 924 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

可以發現,

id

age

sex

欄位都是int型別,這是q命令自動從文字資料中分析出來的。