Bob Mesibov 发布的文章

命令行审计不会影响数据库,因为它使用从数据库中释放的数据。

我兼职做数据审计。把我想象成一个校对者,校对的是数据表格而不是一页一页的文章。这些表是从关系数据库导出的,并且规模相当小:100,000 到 1,000,000条记录,50 到 200 个字段。

我从来没有见过没有错误的数据表。如你所能想到的,这种混乱并不局限于重复记录、拼写和格式错误以及放置在错误字段中的数据项。我还发现:

  • 损坏的记录分布在几行上,因为数据项具有内嵌的换行符
  • 在同一记录中一个字段中的数据项与另一个字段中的数据项不一致
  • 使用截断数据项的记录,通常是因为非常长的字符串被硬塞到具有 50 或 100 字符限制的字段中
  • 字符编码失败产生称为乱码的垃圾
  • 不可见的控制字符,其中一些会导致数据处理错误
  • 由上一个程序插入的替换字符#Replacement_character)和神秘的问号,这是由于不知道数据的编码是什么

解决这些问题并不困难,但找到它们存在非技术障碍。首先,每个人都不愿处理数据错误。在我看到表格之前,数据所有者或管理人员可能已经经历了 数据悲伤 Data Grief 的所有五个阶段:

  1. 我们的数据没有错误。
  2. 好吧,也许有一些错误,但它们并不重要。
  3. 好的,有很多错误;我们会让我们的内部人员处理它们。
  4. 我们已经开始修复一些错误,但这很耗时间;我们将在迁移到新的数据库软件时执行此操作。
  5. 移至新数据库时,我们没有时间整理数据; 我们需要一些帮助。

第二个阻碍进展的是相信数据整理需要专用的应用程序——要么是昂贵的专有程序,要么是优秀的开源程序 OpenRefine 。为了解决专用应用程序无法解决的问题,数据管理人员可能会向程序员寻求帮助,比如擅长 PythonR 的人。

但是数据审计和整理通常不需要专用的应用程序。纯文本数据表已经存在了几十年,文本处理工具也是如此。打开 Bash shell,您将拥有一个工具箱,其中装载了强大的文本处理器,如 grepcutpastesortuniqtrawk。它们快速、可靠、易于使用。

我在命令行上执行所有的数据审计工作,并且在 “cookbook” 网站上发布了许多数据审计技巧。我经常将操作存储为函数和 shell 脚本(参见下面的示例)。

是的,命令行方法要求将要审计的数据从数据库中导出。而且,审计结果需要稍后在数据库中进行编辑,或者(数据库允许)将整理的数据项导入其中,以替换杂乱的数据项。

但其优势是显著的。awk 将在普通的台式机或笔记本电脑上以几秒钟的时间处理数百万条记录。不复杂的正则表达式将找到您可以想象的所有数据错误。所有这些都将安全地发生在数据库结构之外:命令行审计不会影响数据库,因为它使用从数据库中释放的数据。

受过 Unix 培训的读者此时会沾沾自喜。他们还记得许多年前用这些方法操纵命令行上的数据。从那时起,计算机的处理能力和 RAM 得到了显著提高,标准命令行工具的效率大大提高。数据审计从来没有这么快、这么容易过。现在微软的 Windows 10 可以运行 Bash 和 GNU/Linux 程序了,Windows 用户也可以用 Unix 和 Linux 的座右铭来处理混乱的数据:保持冷静,打开一个终端。

 title=

例子

假设我想在一个大的表中的特定字段中找到最长的数据项。 这不是一个真正的数据审计任务,但它会显示 shell 工具的工作方式。 为了演示目的,我将使用制表符分隔的表 full0 ,它有 1,122,023 条记录(加上一个标题行)和 49 个字段,我会查看 36 号字段。(我得到字段编号的函数在我的网站上有解释)

首先,使用 tail 命令从表 full0 移除标题行,结果管道至 cut 命令,截取第 36 个字段,接下来,管道至 awk ,这里有一个初始化为 0 的变量 big ,然后 awk 开始检测第一行数据项的长度,如果长度大于 0 ,awk 将会设置 big 变量为新的长度,同时存储行数到变量 line 中。整个数据项存储在变量 text 中。然后 awk 开始轮流处理剩余的 1,122,022 记录项。同时,如果发现更长的数据项时,更新 3 个变量。最后,它打印出行号、数据项的长度,以及最长数据项的内容。(在下面的代码中,为了清晰起见,将代码分为几行)

tail -n +2 full0 \
> | cut -f36 \
> | awk 'BEGIN {big=0} length($0)>big \
> {big=length($0);line=NR;text=$0} \
> END {print "\nline: "line"\nlength: "big"\ntext: "text}'

大约花了多长时间?我的电脑大约用了 4 秒钟(core i5,8GB RAM);

现在我可以将这个长长的命令封装成一个 shell 函数,longest,它把第一个参数认为是文件名,第二个参数认为是字段号:

现在,我可以以函数的方式重新运行这个命令,在另一个文件中的另一个字段中找最长的数据项,而不需要去记忆这个命令是如何写的:

最后调整一下,我还可以输出我要查询字段的名称,我只需要使用 head 命令抽取表格第一行的标题行,然后将结果管道至 tr 命令,将制表位转换为换行,然后将结果管道至 tailhead 命令,打印出第二个参数在列表中名称,第二个参数就是字段号。字段的名字就存储到变量 field 中,然后将它传向 awk ,通过变量 fld 打印出来。(LCTT 译注:按照下面的代码,编号的方式应该是从右向左)

longest() { field=$(head -n 1 "$1" | tr '\t' '\n' | tail -n +"$2" | head -n 1); \
tail -n +2 "$1" \
| cut -f"$2" | \
awk -v fld="$field" 'BEGIN {big=0} length($0)>big \
{big=length($0);line=NR;text=$0}
END {print "\nfield: "fld"\nline: "line"\nlength: "big"\ntext: "text}'; }

注意,如果我在多个不同的字段中查找最长的数据项,我所要做的就是按向上箭头来获得最后一个最长的命令,然后删除字段号并输入一个新的。


via: https://opensource.com/article/18/5/command-line-data-auditing

作者:Bob Mesibov 选题:lujun9972 译者:amwps290 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

如果你喜欢做‘排名前10’之类的列表但又有点不好意思这样说,那么告诉人们你热爱数据的探索。为了进一步打动他们,向他们解释你在命令行间的数据探索。但是不要告诉他们这其实很容易,以免你的好形象就这样被毁灭了哦!

在这篇文章中,我将基于GNU/Linux工具和'单列表格'(也就是我所说的简单列表)来做一些数据探索。如若想在这里通过命令行查看更多的信息,请查看'man'页,或者在“注释”部分求解。

密码

在第一个列表里探讨的是马克.伯内特2011著的关于10000 个最常用的密码汇编。这个列表是有序的、使用最频繁的,也是广为人知的阶乘“密码”的最常用来源之一,与“123456”并列排名第二。在这里,我把该列表放到一个名为“passwords”的文件中,并且使用head命令把排名前10的列出来了:

(伯内特解释他是如何收集这些密码的这里。你会注意到在列表中他把所有大写字母都转换成小写的。)

OK,所以'password'是伯内特列表的顶部。那么每个数字呢?

非常有趣的是!数字'1'出现在密码列表中的次数多于第二个最常用数字'2'的两倍,而且,除了0和9之外,这十个数字出现的次数以其数字顺序排列。而排名前10的字母呢?

在 passwords 文件中出现最频繁的字母依次是EARONISTLC,类似于EAIRTONSLC,这是至少一个出版的表格中提到的常用英文单词中出现的字频。这是否意味着,大部分密码其实是一些常见的英语单词呢,也许会参杂一些数字呢?

为了找到答案,我先把密码转换成一个纯字母的字符串列表,然后看看有多少字符串是可以在英语词典中找到的。

首先我将通过 sed 命令删除所有密码中的数字,然后删除所有的标点符号,再删除所有的空行。这将创建出一个纯字母的密码列表。然后我通过sortuniq来修剪列表的排序,将重复项取出。(例如,'abc1234def'和'abc1!2!3!def!'都剔除剩下'abcdef'.) 。根据wc命令,我把1000个密码减至成8583个纯字母的字符串:

我经常使用一本便携式的英语字典,我通常会使用usr/share/dict/american-english,这个文件是来自Debian Linux的一个发行版本。它包含了99171个单词。我会先通过tr命令将这个词表转换为纯小写的,然后使用sortuniq删除掉任何重复的条目排序(例如'A' 和 'a' 都将成为 'a')。这样就将词表的数量减至97723项了:

我现在可以用comm命令及'-23'的参数来比较两个列表,并报告纯字母文件中而没有出现在字典中的单词:

总数是3137,所以至少有8583 -3137 = 5446个'核心'密码在伯纳特的纯小写字母列表中(大约63%)是简单的英语单词,或者是简单的单词附加一些数字或者标点符号。我之所以说“至少”,是因为在3137个字符串中有很大比例是只有经过轻微修改的纯英语单词、名称、或者在/usr/share字典中未能找到的名称修改而成的。在LA项中,例如,'labtec', 'ladyboy', 'lakeside', 'lalakers', 'lalala', 'laserjet', 'lasvegas', 'lavalamp' 和 'lawman'.

地名

在之前的一篇Linux Rain article,我描述了如何建立一张37万项澳大利亚的地名表。有了它,我现在可以回答一些类似这样的关键问题“Round Hill是澳大利亚山脉中最流行的名字吗?”和“桑迪是沙滩之最,而岩溪峡谷呢?”

在地名表中地名字段的排名第2,所以这里有:

哇。我当时甚至没有关闭这个终端。(但是请注意到我是如何通过^string1^string2命令保存打印的内容。它重复着最后一个命令,但是用第2个字符串代替了第1个字符串。这是多么有用的BASH绝招!)

另一个亟待解决的问题是有多少地名有'Mile'在其中,例如'Six Mile Creek',而他们的排名又是如何:

我在我的澳洲之旅发现有很多Dead Horse Creeks,因此有这些地名:

种类

第三个列表是探索我今年出版的1961-2010年期间澳大利亚新种类昆虫名。从这个列表中,我去掉所有“物种的绰号”,就是种群组合的第二部分,比如像智人(你和我)和西方蜜蜂(欧洲蜜蜂)。

(科技小贴士:这个昆虫表,可以从开发数据Zenodo库中https://zenodo.org/record/10481取得,包括亚种。在我的‘top 10’练习中,我首先分离出所有独特的种群组合,这样避免了重复的,例如蜜蜂iberica的亚种,以避免蜜蜂的绰号intermissa,等等。最后一个物种文件有18155个绰号。)

大多数人讲科学名称带玩笑式地用'-us'结局,如'Biggus buggus'。那么昆虫学家呢?有几个不错的,用命令行的方式获取字符串的最后2个字母,在这里我都会用到这2个:

耶!昆虫学家喜欢也‘-us’结尾。接下来,我不知道有多少物种是以我的家乡Tasmania州来命名的?(下面我想看看前100行,来确保我得到的所有'tasman'组合.)

那么昆士兰呢?

一般来说,昆虫物种名单中的前10名分别是什么呢?

嗯,除了明显的'australis'和'australiensis',而地理方面的'occidentalis'(西部),另外昆虫学家创建7个在10个最流行列表中的绰号已经履行了其它昆虫学家的意愿。(绰号'commoni'是给澳大利亚蝴蝶和蛾专家Ian F.B. Common[1917-2006]的荣誉。)

演变

上面的这些命令用在简单列表上。要从简单的列表变成文本块,那就再次需要我们的命令行朋友了。例如,我把澳大利亚参议院于2014年7月16日的演讲保存成文本文件hansard。将hansard分割成一个单词列表:

现在看看讲话中的单词使用频率:

即将推出...

从多列的表中做'top 10'等排名,需要更多些的命令行工具。我将会在未来的文章中证明他们的用处。


via: http://thelinuxrain.com/articles/top-10-fun-on-the-command-line

原文作者:Bob Mesibov(Bob Mesibov 是塔斯马尼亚人,已经退休,热衷于 Linux tinkerer)

译者:disylee 校对:wxy

本文由 LCTT 原创翻译,Linux中国 荣誉推出