大家好,今天聊一个程序员都绕不开的命令:grep。
只用过
findstr或Select-String的 Windows 宝子们可以下车喽,拜拜~
说起 grep,大多数程序员脑海里浮现的应该是终端上的一行命令,或单独使用,或接入管道(|),或多次“自身接龙”(... | grep ... | grep ...),然后一堆结果就“唰”地跳出来。既可用于日志分析,又能用来搜索代码,grep 已经成了 Unix 世界里最具代表性的工具之一。
但你知道吗?关于 grep 的起源,有个“一夜而就”的传说。
故事要追溯到 1970 年代初,Unix 还是萌芽期的时代。
那时, Unix 上的标准文本编辑器是 Unix 的缔造者之一 Ken Thompson 写的 ed。虽然 ed 是最早一批支持正则表达式的行编辑器之一,但它有个致命问题:只有把整个文件读进内存后才能操作。因此,在当年那点可怜的内存面前,几十 KB 的文本就已经让 ed 吃不消,更别说去分析成百上千页的文稿了。
在屏幕式编辑器(如 vi、nano)出现之前,用户只能使用行编辑器(line editor)。在 1960–70 年代,操作计算机的工具是电传打字机 —— 一种带键盘的低速打印机 —— 没有显示屏,也无法在文本中自由移动光标。于是,行编辑器的操作就以“行”为单位,每条命令作用于一行或多行文本。
Ken 的同事 Lee McMahon 是个语言学家,他当时在研究一件大事:通过文本分析,判断美国《联邦党人文集》(The Federalist Papers)的确切作者。这些文集共有 85 篇,署名是“Publius”,究竟哪篇是谁写的,一直是学界争论的焦点。
McMahon 想用计算机分析这些文档中的模式,看看能不能找出一些语言学上的规律。问题是:这 85 篇文档加起来超过了 1 MB —— 以今天的标准来看几乎微不足道 —— 但当时的计算机内存根本放不下。
于是他找到 Ken Thompson,提了个需求:
“嗨,我只想在这些文章里找出那些包含某个词的行,别的啥都不要。能不能搞个工具?”
Ken 点点头,“行,我回头搞一个”。
一夜过去。
没想到第二天,Ken 就已经把写好的程序交给 McMahon 了。这个小工具能在一个或多个文件里,顺序扫描所有内容,把匹配正则表达式的行找出来。这个小工具的名字正是 grep。
于是就有了 grep 是 Ken 一夜之间写出来的传说。
其实,Ken 并不是“熬了一夜爆肝”从零开始写 grep 的。他早就写过个叫 s 的私人工具,用来做与 grep 类似的事情。McMahon 来提需求时,Ken 只是花些时间,把代码修修补补一番,以便跑得更稳健,然后就交了出去。
所以“grep 是一夜之间写出来的”这个传说,严格来说有点夸张。更真实的情况是:Ken 手头已经有了现成的代码积木,他只是用这些积木迅速重新拼凑出另一个程序,并换了个更有趣的名字。
那 grep 这个名字又是怎么来的呢?为什么不直接用 search、find 这种明显表示“查找、搜索”的词呢?
还是要回到 ed 编辑器里去找答案。原来在 ed 编辑器里有个命令:
g/<re>/p
意思是:全局搜索(globally)匹配正则表达式(<re>)的行,并把这些行都打印(print)出来。
Ken 把这串命令缩成一个词:grep。而 grep 也由此成了 Unix 世界中从文本中搜索关键词最自然的表达。
McMahon 拿到工具后,顺利地开展了文本分析。而 grep 本身,则被收录进了 Unix 第四版,逐渐成为“Unix 哲学”的象征:
写一个小而精的工具,做好一件事。
🔚