Linux 中用于数据分析的 10 个命令行工具

当终端可以更快、更强大且更容易编写脚本时,为什么要把所有内容都加载到电子表格中?
739 位读者喜欢这篇文章。
Open data brain

Opensource.com

您已经获得了一些想要分析的数据。您从哪里开始?

许多习惯于图形环境的人可能会默认使用电子表格工具,但是还有另一种方法可以证明更快、更有效,只需稍加努力即可。而且,您无需成为统计建模语言或大数据工具集的专家即可利用这些工具。

您可以在不离开终端的情况下了解大量数据集。

我指的是 Linux 命令行。只需使用一些可能已安装在计算机上的工具,您就可以在不离开终端的情况下了解大量数据集。长期使用 Linux 的用户当然会嘲笑,因为他们已经使用其中许多工具多年来解析日志并理解配置工具。但是对于 Linux 新手来说,您已经掌握了整个数据分析工具包这一发现可能会令人惊喜。

而且,这些工具中的大多数并非严格限于 Linux。它们中的大多数可以追溯到 Unix 时代,其他类 Unix 操作系统的用户可能已经安装了它们,或者可以轻松地进行安装。许多工具是 GNU Coreutils 包的一部分,而一些工具则由个人维护,经过一些工作,您甚至可以在 Windows 上使用它们。

 

 

因此,让我们尝试一些用于数据分析的简单开源工具,看看它们是如何工作的!如果您想按照这些示例进行操作,请继续下载此 示例数据文件,该文件来自 GitHub,这是一个 CSV(逗号分隔值)列表,其中包含我们在 1 月份发布到 Opensource.com 的文章。


head 和 tail

首先,让我们从处理文件开始。里面有什么?它的格式是什么样的?您可以使用 cat 命令在终端中显示文件,但是如果您要处理的文件超过几十行,这将对我们没有太大帮助。

输入 headtail。两者都是用于显示文件顶部或底部指定行数的实用程序。如果您没有指定要查看的行数,则会得到 10 行。让我们用我们的文件来试试。

$ tail -n 3 jan2017articles.csv 
02 Jan 2017,Article,Scott Nesbitt,3 tips for effectively using wikis for documentation,1,/article/17/1/tips-using-wiki-documentation,"Documentation, Wiki",710
02 Jan 2017,Article,Jen Wike Huger,The Opensource.com preview for January,0,/article/17/1/editorial-preview-january,,358
02 Jan 2017,Poll,Jason Baker,What is your open source New Year's resolution?,1,/poll/17/1/what-your-open-source-new-years-resolution,,186

查看最后三行,我可以立即挑选出日期、作者姓名、标题和其他一些信息。但是我不知道每一列是什么。让我们看一下文件的顶部,看看它是否有标题来解释每一列的含义

$ head -n 1 jan2017articles.csv 
Post date,Content type,Author,Title,Comment count,Path,Tags,Word count

好的,现在一切都说得通了。看起来我们有一个文章列表,其中包含文章的发布日期、每篇文章的内容类型、作者、标题、评论数、相对 URL、每篇文章的标签以及字数。

wc

太棒了,但是这个文件有多大?我们是在谈论几十篇要分析的文章,还是数百篇,甚至数千篇?wc 命令可以帮助我们。wc 是“word count”(字数统计)的缩写,它可以计算文件中的字节数、字符数、字数或行数。在我们的例子中,我们想知道行数。

$ wc -l jan2017articles.csv 
93 jan2017articles.csv

有了它。此文件中包含 93 行;既然我们知道第一行包含标题,那么我们可以推测这是一个包含 92 篇文章的列表。

grep

好的,现在让我们问自己:在这 92 篇文章中,有多少篇是关于安全主题的?为了我们的目的,假设我们对文章中任何地方提及安全的文章感兴趣,无论是在标题、标签列表还是其他地方。grep 工具可以帮助我们。借助 grep,您可以在文件或其他输入中搜索特定的字符模式。由于您可以构建 正则表达式 来匹配非常精确的模式,因此 grep 是一个非常强大的工具。但是现在,让我们只搜索一个简单的字符串。

$ grep -i "security" jan2017articles.csv
30 Jan 2017,Article,Tiberius Hefflin,4 ways to improve your security online right now,3,/article/17/1/4-ways-improve-your-online-security,Security and encryption,1242
28 Jan 2017,Article,Subhashish Panigrahi,How communities in India support privacy and software freedom,0,/article/17/1/how-communities-india-support-privacy-software-freedom,Security and encryption,453
27 Jan 2017,Article,Alan Smithee,Data Privacy Day 2017: Solutions for everyday privacy,5,/article/17/1/every-day-privacy,"Big data, Security and encryption",1424
04 Jan 2017,Article,Daniel J Walsh,50 ways to avoid getting hacked in 2017,14,/article/17/1/yearbook-50-ways-avoid-getting-hacked,"Yearbook, 2016 Open Source Yearbook, Security and encryption, Containers, Docker, Linux",2143

我们使用的格式是 grep,后跟 -i 标志(告诉 grep 不区分大小写),后跟我们要搜索的模式,然后是我们要在其中搜索的文件。看来我们上个月有四篇与安全相关的文章。但是让我们想象一下,我们得到一个比我们可以轻松计数的列表长得多的列表。使用 管道,我们可以将 grep 与我们刚刚在上面了解到的 wc 命令结合起来,以获取提及安全性的总行数。

$ grep -i "security" jan2017articles.csv | wc -l
4

在这种情况下,wc 采用了 grep 命令的输出,并将其用作其输入,而无需担心首先将其保存到任何地方。这就是管道输入和输出(特别是与一些 shell 脚本 结合使用时)使终端成为如此强大的数据分析工具的原因。

tr

CSV 文件是许多分析场景非常有用的格式,但是如果需要将文件转换为其他格式以在其他应用程序中使用该怎么办?也许您需要制表符分隔符而不是逗号,或者您想将它们更改为一些 HTML,以便可以在表中使用数据输出。tr 命令可以通过将一种类型的字符转换为另一种类型来帮助您。与其他示例一样,您也可以将输入和输出通过管道传输到此命令。

让我们尝试另一个多部分示例,创建一个仅包含 1 月 20 日发布的文章的 TSV(制表符分隔值)文件。

$ grep "20 Jan 2017" jan2017articles.csv | tr ',' '\t' > jan20only.tsv

这里发生了什么?首先,我们使用 grep 搜索有问题的日期。我们将此输出通过管道传输到 tr 命令,我们使用该命令将逗号替换为制表符(用 '\t' 表示)。但是它去哪里了?好吧,> 字符将输出重定向到我们的新文件,而不是屏幕。所有这些工作都在一个命令序列中完成。然后,我们可以验证 jan20only.tsv 文件是否包含我们期望的数据。

$ cat jan20only.tsv 
20 Jan 2017     Article Kushal Das      5 ways to expand your project's contributor base        2       /article/17/1/expand-project-contributor-base    Getting started 690
20 Jan 2017     Article D Ruth Bavousett        How to write web apps in R with Shiny   2       /article/17/1/writing-new-web-apps-shiny Web development 218
20 Jan 2017     Article Jason Baker     "Top 5: Shell scripting  the Cinnamon Linux desktop environment  and more"       0       /article/17/1/top-5-january-20  Top 5   214
20 Jan 2017     Article Tracy Miranda   How is your community promoting diversity?      1       /article/17/1/take-action-diversity-tech Diversity and inclusion 1007

sort

如果我们要了解有关特定列的更多详细信息怎么办?我们新文章列表中哪篇文章最长?让我们以上一个示例为基础。现在我们有了仅来自 1 月 20 日的文章列表,我们可以使用 sort 命令按字数统计列进行排序。当然,从严格意义上讲,我们不需要此处的中间文件;我们可以将上一个命令的输出通过管道传输。但是有时将长步骤分解为较小的步骤比创建巨大的命令链更容易。

$ sort -nr -t$'\t' -k8 jan20only.tsv | head -n 1
20 Jan 2017     Article Tracy Miranda   How is your community promoting diversity?      1       /article/17/1/take-action-diversity-tech Diversity and inclusion 1007

这是另一个很长的示例,因此让我们分解一下发生了什么。首先,我们使用 sort 命令按字数排序。-nr 选项告诉 sort 进行数字排序,并以相反的顺序(从大到小)返回结果。下一个 -t$'\t' 告诉 sort 分隔符是制表符('\t')。(您可以在 此处 阅读为什么需要美元符号;简而言之,它告诉 shell 这是一个需要处理的字符串,以将 \n 转换为实际的制表符)。命令的 -k8 部分告诉 sort 使用第八列,这是我们示例中的字数统计列。

最后,整个输出通过管道传输到 head,并指示仅显示顶行,这是我们的结果,即来自此文件中字数统计最高的文章。

sed

您可能想选择文件的特定行。sed 是流编辑器(stream editor)的缩写,是执行此操作的一种方法。如果想合并多个具有标题的文件怎么办?您只想为整个文件显示一组标题,因此您需要一种方法来删除多余的标题。或者,如果您只想获取特定范围的行怎么办?sed 是您的工具。这也是批量查找和替换文件的好方法。

让我们从文章列表中创建一个没有标题的新文件,适合与其他文件合并(例如,如果我每个月都有一个不同的文件,并且想将它们放在一起)。

$ sed '1 d' jan2017articles.csv > jan17no_headers.csv

'1 d' 选项告诉 sed 删除第一行。sed 的功能远不止这些,我建议您进一步阅读有关其 替换功能

cut

如果我不想删除一行,而是想删除一列怎么办?如果我想只挑选一列怎么办?让我们为上面构建的示例创建一个新的作者列表。

$ cut -d',' -f3 jan17no_headers.csv > authors.txt

在这个简单的示例中,我们用 -d',' 告诉 cut 这是一个逗号分隔的文件,我们想要第三列(-f3),并将输出发送到一个名为 authors.txt 的新文件。

uniq

上一个例子给我们留下了一个作者列表,但是,这个列表中有多少个唯一的作者呢?每位作者写了多少篇文章?试试 uniq 命令。使用 uniq,你可以轻松找到答案。让我们对文件进行排序,找到唯一的作者,然后输出一个文件,其中包含每位作者撰写的文章数量。

sort authors.txt | uniq -c > authors-sorted.txt

浏览一下文件,我们现在可以看到每位作者有多少篇文章。让我们只看一下最后三行来确保它工作正常。

$ tail -n3 authors-sorted.txt
      1 Tracy Miranda
      1 Veer Muchandi
      3 VM (Vicky) Brasseur

awk

今天我们来看一下命令行数据分析工具箱中的另一个工具, awkawk 是我将给予过少评价的另一种工具;它实际上是一个功能强大的工具,值得单独探索。它是另一个很棒的替换工具,但功能远不止于此。让我们回到之前制作的仅包含 1 月 20 日文章的 TSV 文件,并使用它创建一个仅包含这些文章作者以及每位作者撰写的字数的列表。

$ awk -F "\t" '{print $3 "  " $NF}' jan20only.tsv
Kushal Das  690
D Ruth Bavousett  218
Jason Baker  214
Tracy Miranda  1007

这是怎么回事? 我们传递给 awk-F "\t" 只是告诉它我们正在处理制表符分隔的数据。 在花括号内,我们实际上是在告诉 awk 执行一小段代码。 我们告诉它打印第三列 $3,然后打印最后一列 $NF(“字段数”),并在它们之间放置两个空格,使其更具可读性。


那又怎样呢? 我们不能在电子表格中更快地完成所有这些工作,或者只是在某些情况下查看文件吗? 当然可以! 现在停下来想象一下,我们处理的不是一个 93 行的文件,而是一个 93,000 行甚至更大的文件。 您的电子表格实用程序是否可以在不崩溃或显着减慢速度的情况下加载它? 或者想象一下,我们不是有一个包含一个月文章的文件,而是有过去七个月中每个月都有一个不同的文件。 突然,电子表格不是处理数据的最佳选择,但你还没有真正进入需要真正的 *大数据工具* 来处理数据集的领域。

你可以选择将文件加载到数据库工具中,并在那里处理数据。 但这是正确的选择吗? 这可能有点过头了。 如果你只是在检查数据以了解它包含什么呢? 借助这些简单的工具和一些脚本来递归遍历目录,你可以轻松地处理大量数据。 经常处理数据的专业人士和业余爱好者都应该花一些时间学习这些和其他命令行数据分析工具。

这个介绍只是触及了每个工具的表面。 它们远比这些简单的例子所能展示的强大得多,这就是为什么关于它们的大部分都写成了书卷。 我希望你花时间阅读手册页,在搜索引擎中做一些工作,或者拿起一本书,更多地了解你手头现成的这一有趣的工具套件。

标签
Jason Baker
前红帽员工。 现在是一名顾问和有抱负的企业家。 地图爱好者、制造者和开源桌面及自托管软件的热情安装者。

11 条评论

我总是抽不出时间,但我一直在暗示自己需要为这些命令制作自己的参考资料。 我会找到其中一个的用途,花一些时间整理语法,将手册页翻译成人类可读的内容,并做一些非常酷的事情。 不幸的是,如果我有一段时间没有使用它们,我会忘记细节,并且不得不重新学习。

记住确切的参数格式和顺序对于这些工具来说绝对是一个挑战;我确实为了这个目的保留了自己的笔记。 对于大多数工具(当然 sed 和 awk 除外),与其费力地阅读手册页,不如使用 --help 运行它们,这将为你提供足够的想法来解决你的需求。

回复 ,作者是 Greg P

我唯一真正不使用的是 tr。 我发现使用 sed 或 awk 脚本将我的文件转换为 XML 更容易,该脚本可以使用带有自定义格式的 XSLT 轻松转换为电子表格 XML 2003。

谢谢。
一个评论...我认为“sort authors.txt | uniq -c > authors.txt”这行会清空 authors.txt

好的发现;我更改了输出文件的名称。 谢谢!

回复 ,作者是 Rob Kellington (未验证)

我使用所有这些工具。 你可以用它们做疯狂的事情。 但在大多数情况下,它仅适用于批量工作。 你忘记了 PERL,它包括你提到的所有工具的可能性。 甚至还有一个 PERL 模块可以创建 Excel 表格。 ;-)

我们常用的管道线是
grep /tmp/file | cut -d: -f1,2 | sort | uniq -c

例如,计算每分钟 IP 的命中次数
grep 24.333.222.111 /var/log/httpd/access_log | cut -d: -f2,3 | sort | uniq -c
70 23:45
74 23:46
76 23:47
36 23:48

perl 为你提供 sed、awk 和 grep 的所有功能,并将它们结合并扩展。 它在管道线中运行良好。

Jason,当你说“只需付出一点努力”时,我认为你必须澄清这意味着学习这些工具,因为当你熟悉这些工具时,就会转化为更少的工作量。 另一个重要的注意事项是你可以开发自己的自定义工具,此时你将成为一名忍者。 谢谢!

很棒的文章 :-) 另一个非常方便的命令行工具是“Petit”。 它可以哈希一个文件,这在查看日志文件时非常有用,因为日期戳可能会在一行上更改,而你希望将事件分组在一起。 例如,如果你正在查找 URL 或 IP 地址上的所有行为,你可以总结日志并获得更清晰的画面。 当我看到脚本多次访问一个页面并想要该 URL 的 IP 列表时,我发现它很有用。

方便的小工具 :-)

我经常用于数据分析的两个命令行工具是 jq 和 q
- jq 是一个“命令行 JSON 处理器”。 有时我会从我的 curl 命令中得到冗长且丑陋的 JSON 响应。 我会通过管道将其输入到 jq 中,并删除所有我不想要的 JSON 部分,并且它也被很好地打印出来。
- q 允许我对 CSV 文件运行类似 SQL 的查询。 我甚至可以进行连接! 当然,它只对了解 SQL 查询的人有用,但不如我希望的那么多,但由于我知道如何执行它们,因此它派上了用场。

很棒的补充! 在这篇文章中,我想专注于默认安装在大多数 Linux 系统上的工具,但我认为还有许多关于其他工具的潜在后续行动。 也许你想写写这些工具?

回复 ,作者是 sriley

Creative Commons License本作品采用知识共享署名-相同方式共享 4.0 国际许可协议进行许可。
© . All rights reserved.