商用的数据处理工具有明确要求的运行环境,在非目标领域内可能完全无法开展工作。类似于 Python 的自助式工具则形如瑞士军刀,具备各类环境的实用性,但对使用人员要求较高。在个别场合下,Python 之流可能也过于麻烦了,比如需要联网下载各种包。此时,最为传统的命令行工具可能大放异彩。

需要说明的是,在生产环境中,目前已经不可能以命令行工具作为核心了。新的工具都是为了解决老工具的问题而诞生的。工具的选择应当兼顾最大化工作效率和最优化工程效率两个目的。所以此类工具的知识,大概率属于锦上添花。本文只为了指出,在极少数场景下(比如词频统计、文本清洗),数据工作者仍然可以单纯依靠命令行工具来完成工作。

《命令行中的数据科学》对此类工具有普及性的介绍,此书也展示了在命令行中使用 python 和 r 的方法,不属于本文介绍的范围(还不如直接用最新的 IDE)。

此类工具举例:

  • sed
  • awk
  • grep
  • tr
  • jq
  • gnuplot

案例

(这是一个真实的案例,不过数据量只在千万行级别。只做功能概念的展示。在 python 大行其道的当下,估计大部分人会通过 python 完成吧。)

某服务器日志以纯文本形式存储,每行一条记录,每条记录是以空格分割,现在希望快速统计服务器接口的每日请求数量。日志格式并不复杂,甚至可以通过 excel 处理,但是经估算,行数较大,excel 可能无法打开。所以尝试通过上述工具处理。

  1. 127.0.0.1 - - [25/Oct/2021:19:15:40 +0800] "GET /page/detail?index=462 HTTP/2.0" 200 10269 "https://appservice.qq.com/" "Mozilla%2F5.0+%28Linux%3B+Android+10%3B+HLK-AL00+Build%2FHONORHLK-AL00%3B+wv%29+AppleWebKit%2F537.36+%28KHTML%2C+like+Gecko%29+Version%2F4.0+Chrome%2F78.0.3904.108+Mobile+Safari%2F537.36 QQ/8.8.0.5420 V1_AND_SQ_8.8.0_1792_YYB_D QQ/MiniApp"

观察日志格式,需要的信息是[25/Oct/2021:19:15:40 +0800]"GET /page/detail?index=462 HTTP/2.0",只需要一行命令即可 awk '{print substr($4,2,11),$7}' log.txt 。返回的结果如下是 25/Oct/2021 /page/detail?index=462。awk 根据空格分列,取出指定的第4列的第2到11个字符,就是日期部分,取出第7列,就是 url 部分。虽然直接按列获取,并不是直接按语义处理,但在这个案例中,仍然获得了我们需要的内容。

此时返回的结果包含了 URL 中的 query 部分,只需要保留问号前的部分。将前述命令的返回结果供给 cut 命令,并存入 log_parsed 文件,awk '{print substr($4,2,11),$7}' log.txt | cut -d ? -f 1

此时,log_parsed 文件的数据量仍然不适合在 excel 中查看,我们需要借助 csvsql 来汇总计算。csvsql 是 csvkit 的一部分,需要先 pip install csvkit 来安装。为了便于 csvsql 的使用,还需要做一些准备工作。

下面直接给出所有的命令行。此时,log_stat 中的数据可以通过 excel 来查看了。

## 先安装 csvkit
pip3 install csvkit

## 先后执行命令,log.txt 换成对应的日志文件
echo 'date url' > log_parsed
awk '{print substr($4,2,11),$7}' log.txt | cut -d ? -f 1 >> log_parsed
cat log_parsed | csvsql --query 'SELECT date, url, count(1) as pv  FROM stdin GROUP BY date, url ORDER BY date, pv DESC' > log_stat
cat log_stat