学习使用 Sed 文本编辑器
Sed 缺少通常的文本框,而是按照用户的命令直接写入到文件上。
sed
命令是为 AT&T 最初的 Unix 操作系统第 7 版创建的,此后,可能每一个 Unix 和 Linux 操作系统都包含了它。sed
应用程序是一个 流编辑器,与文本编辑器不同的是,它不会打开一个视觉缓冲区,将文件的数据加载到其中进行处理。相反,它根据在终端输入的命令或脚本中的一系列命令,逐行对文件进行操作。
安装
如果你使用的是 Linux、BSD 或 macOS,那么你已经安装了 GNU 或 BSD 版的 sed
。这是两个不同的原始 sed
命令的重新实现,虽然它们很相似,但也有一些小的区别。GNU sed
通常被认为是功能最丰富的 sed
,而且它在这些平台上都可以广泛使用。
如果你找不到 GNU sed
(在非 Linux 系统上通常被称为 gsed
),那么你可以从 GNU 网站上下载它的源代码。安装 GNU sed
的好处是,可以使用它的额外功能,但它也可以被限制为只符合 sed
的 POSIX 规范,如果你需要移植性的话。
在 Windows 上,你可以用 Chocolatey 来安装 GNU sed
。
Sed 如何工作
sed
应用程序一次只处理一行。因为它没有视觉显示,所以它在内存中创建了一个模式空间:一个包含输入流的当前行的空间(去掉任何尾部的换行符)。一旦填充了模式空间,你对 sed
的指令就会被执行。有时你的指令是有条件的,有时是无条件的,所以这些指令的结果取决于你如何使用 sed
。
当命令结束时,sed
会将模式空间的内容打印到输出流中。默认的输出流是标准输出,但可以将其重定向到一个文件,甚至使用 --in-place=.bak
选项重定向到同一个文件中。
然后再从下一个输入行开始循环。
sed
命令的语法是:
1 |
|
找到你要编辑的内容
在可视化编辑器中,你通常不需要考虑太多,就能在文本文件中找到你想要修改的内容。你的眼睛(或屏幕阅读器)会扫描文本,找到你想改变的单词或你想插入或删除文本的地方,然后你就可以开始输入了。而 sed
没有交互模式,所以你需要告诉它必须满足什么条件才能运行特定的命令。
在这些例子中,假设一个名为 example.txt
的文件包含了这样的文字:
1 |
|
行号
指定行号告诉 sed
只对文件中的那一行进行操作。
例如,下面这条命令选择文件的第 1 行并打印出来。因为 sed
在处理后的默认操作也是打印一行到标准输出,这样做的效果就是重复第一行:
1 |
|
你也可以步进式指定行号。例如,1~2
表示每两行选择一行(“从第一行开始每两行选择一行”)。指令 1~3
表示从第一行开始,每三行选择一行:
1 |
|
行定位
你可以通过使用 $
作为选择器,只对文件的最后一行进行操作:
1 |
|
在 GNU sed
中,你可以选择多行(例如,sed '1,$p'
打印第一行和最后一行)。
反转
任何数字或位置的选择,你都可以用感叹号(!
)字符反转。下面这将选择除第一行以外的所有行:
1 |
|
模式匹配
你可以把模式匹配想象成文字处理器或浏览器中的查找操作。你提供一个词(一个 模式),然后选择了结果。模式匹配的语法是 /pattern/
:
1 |
|
用 Sed 编辑
一旦你找到了你要编辑的内容,你就可以执行你想要的任何操作。你可以用 sed
中的命令来执行编辑。sed
中的命令不是 sed
命令本身。如果这样说有帮助的话,可以把它们看作是“动作”或“动词”或“指令”。
sed
中的命令是单个字母,例如前面例子中使用的打印命令的 p
。它们一开始可能很难记忆,但和所有事情一样,你会随着练习而了解它们。
p 代表打印
p
指令打印当前模式空间中的任何内容。
d 用于删除
d
指令删除模式空间:
1 |
|
s 用于搜索和替换
s
命令搜索一个模式并将其替换为其他东西。这可能是 sed
最流行和最随意的用法,而且它通常是用户学习的第一个(有时也是唯一的)sed
命令。几乎可以肯定它是文本编辑中最有用的命令:
1 |
|
在你的替换文本中,也可以使用一些特殊的功能。例如,\L
将替换文本转换为小写,\l
则只转换下一个字符。还有其他一些功能,列在 sed
文档中(你可以用 info sed
命令查看)。
替换子句中的特殊字符 &
指的是匹配到的模式:
1 |
|
你也可以通过特殊的标志来影响 s
如何处理它找到的内容。g
(应该是指 全局)标志告诉 s
对行上找到的所有匹配项进行替换,而不仅仅是第一个匹配项:
1 |
|
其他重要的标志还包括用一个数字来表示要影响第几个出现的匹配模式:
1 |
|
w
标志,后面跟着一个文件名,_只有_在有变化的情况下,才会将匹配的行写入文件:
1 |
|
标志可以组合:
1 |
|
脚本
有很多很棒的网站都有 sed
“单行脚本”,它们给你提供了面向任务的 sed
命令来解决常见的问题。然而,自己学习 sed
可以让你写出自己的单行脚本,而且这些单行脚本可以根据你的具体需求来定制。
sed
的脚本可以在终端中写成一行,也可以保存到文件中,然后用 sed
本身执行。我倾向于把小脚本写成一个命令,因为我发现自己在现实生活中很少重复使用 sed
命令。当我写一个 sed
脚本时,通常都是针对一个文件的。例如,在写完这篇文章的初稿后,我用 sed
来规范 “sed” 的大小写,而这是我可能永远也不会再做的任务。
你可以向 sed
发出一系列不同的命令,用分号(;
)分开。
1 |
|
带括号的范围改变
你也可以用大括号({}
)限制哪些结果受到影响。当你将 sed
命令用大括号括起来时,它们只适用于特定的选择。例如,“line” 字出现在样本文本的两行中。你可以通过声明所需的匹配条件($
表示最后一行),并将你希望执行的 s
命令放在紧随其后的括号中,强制 sed
只影响最后一行:
1 |
|
学习 Sed
你可以用 sed
做的事情比本文所解释的多得多。我甚至还没有涉及到分支(b
)、测试(t
)、保留空格(H
)和许多其他功能。就像 ed 一样,sed
可能不是你要用来创建文档的文本编辑器,甚至不是你需要做的每一个脚本任务中使用的文本编辑器,但它是你作为 POSIX 用户的一个强大的选择。学习 sed
命令的结构以及如何编写简短的脚本可以快速修改大量的文本。阅读 GNU sed
的info
页面,或者 BSD sed
的手册页,看看 sed
能为你做什么。
via: https://opensource.com/article/20/12/sed
作者:Seth Kenlon 选题:lujun9972 译者:wxy 校对:wxy