每个 Linux 极客都需要了解 Sed 和 Awk。这就是为什么……
sed 和 awk 是每个 Linux 高级用户最喜欢的工具。但它们是什么?以及如何使用它们来处理文本文件?
两个最不受重视的 Linux 实用程序是 sed 和 awk。尽管它们看起来有点神秘,但如果您必须对大段代码或文本进行重复更改,或者如果您必须分析某些文本,sed 和 awk 的价值是无价的。
那么,它们是什么?它们是如何使用的?当它们结合起来时,如何使文本处理变得更容易?
什么是 sed?
sed 于 1971 年由传奇计算先驱 Lee E. McMahon 在贝尔实验室开发。
该名称代表“流编辑器”。 sed 允许您通过紧凑、简单且图灵完备的编程语言以编程方式编辑文本体或文本流。
sed 的工作方式很简单:它将文本逐行读入缓冲区。对于每一行,它将执行预定义的指令(如果适用)。
例如,如果有人要编写一个 sed 脚本,将“啤酒”一词替换为“苏打水”,然后传入一个包含“墙上的 99 瓶啤酒”完整歌词的文本文件,它将通过逐行归档,并打印出“墙上有 99 瓶苏打水”,依此类推。
最基本的 sed 脚本是“Hello World”。在这里,我们使用 echo 命令(仅输出字符串)来打印“Hello World”。但我们将其通过管道传递给 sed,并告诉它用“Dave”替换“World”。不言自明的东西。
echo "Hello World" | sed s/World/Dave/
如果需要进行一些更复杂的编辑,您还可以将 sed 指令合并到文件中。受到这个热闹的 Reddit 帖子的启发,让我们将 A-ha 的“Take On Me”的歌词替换为 Greg 中的“I”、“Me”和“My”。
首先,将歌曲的歌词放入名为 tom.txt 的文本文件中。然后打开您喜欢的文本编辑器,并添加以下行。确保您创建的文件以 .sed 结尾。
s/I/Greg/
s/Me/Greg/
s/me/Greg/
s/My/Greg/
s/my/Greg/
您可能会注意到上面示例中的重复(例如 s/me/Greg/ 和 s/Me/Greg/)。这是因为某些版本的 sed(例如 macOS 附带的版本)不支持不区分大小写的匹配。因此,我们必须为每个单词编写两条指令,以便 sed 识别大写和非大写版本。
这不会完美地工作,就好像您手动替换了“I”、“Me”和“My”的每个实例一样。请记住,我们只是将此作为练习来演示如何将 sed 指令分组到一个脚本中,然后使用单个命令执行它们。
然后,我们需要调用该文件。为此,请运行此命令。
cat tom.txt | sed -f greg.sed
让我们放慢脚步,看看这是做什么的。您可能已经注意到,我们在这里没有使用 echo。我们用的是猫。这是因为 cat 会打印出文件的全部内容,而 echo 只会打印出文件名。您可能还注意到我们正在使用“-f”标志运行 sed。这告诉它将脚本作为文件打开。
最终结果是这样的:
还值得注意的是 sed 支持正则表达式 (REGEX)。这些允许您使用特殊且复杂的语法来定义文本中的模式。
这是一个如何运作的示例。我们将采用上述歌词,但使用正则表达式打印出不以“Take”开头的每一行。
cat tom.txt | sed /^Take/d
当然,sed 非常有用。但与 awk 结合使用时,它的功能会更加强大。
什么是 AWK?
AWK 与 sed 一样,是一种处理大量文本的编程语言。但是,虽然人们使用 sed 来处理和修改文本,但人们主要使用 AWK 作为分析和报告工具。
与 sed 一样,AWK 最初是在 20 世纪 70 年代由贝尔实验室开发的。它的名字并非来自该程序的功能,而是来自每个作者的姓氏:Alfred Aho、Peter Weinberger 和 Brian Kernighan。全部大写时,AWK 指的是编程语言本身。小写的 awk 指的是命令行工具。
AWK 的工作原理是一次读取一行文本文件或输入流。扫描每一行以查看其是否与预定义的模式匹配。如果找到匹配项,则执行操作。
但是,虽然 sed 和 AWK 可能具有相似的用途,但它们是两种完全不同的语言,具有两种完全不同的设计理念。 AWK 更类似于一些通用语言,例如 C、Python 和 Bash。它有函数之类的东西,以及迭代和变量之类的更像 C 的方法。简而言之,AWK 感觉更像是一种编程语言。
那么,让我们尝试一下。使用“Take On Me”的歌词,我们将打印所有长度超过 20 个字符的行。
awk ' length($0) > 20 ' tom.txt
两者结合
awk 和 sed 结合起来都非常强大。您可以使用 Unix 管道来完成此操作。这些是“|”命令之间的位。
让我们尝试一下:我们将使用 awk 列出“Take On Me”中所有超过 20 个字符的行。然后,我们将删除所有以“Take”开头的行。总的来说,一切看起来像这样:
awk 'length($0)>20' tom.txt | sed /^Take/d
并产生这个:
sed 和 awk 的强大功能
在一篇文章中您只能解释这么多,但希望您现在已经感受到 sed 和 awk 的强大功能有多么强大。简而言之,它们是文本处理引擎。
那么,你为什么要关心呢?好吧,除了您永远不知道何时需要对文本文档进行可预测的重复更改这一事实之外,sed 和 awk 非常适合解析日志文件。当您尝试调试 LAMP 服务器中的问题或查看访问日志以查看服务器是否已被黑客攻击时,这尤其方便。