文章

sed 命令使用小结

做毕设时需要用到对文本的批量编辑处理,因而学习了 sed。这里记录一下 sed 命令的使用方法。

做毕设时需要用到对文本的批量编辑处理,因而学习了 sed。这里记录一下 sed 命令的使用方法。

本文主要是对 GNU 官网使用说明书的翻译和读书笔记,辅以一些网络上还可以的前人学习笔记做参考。

本文没有写完,凑活看吧。心情好的话会再更新直到我不玩 Linux Shell 了为止


概述

sed的全称是“stream editor” ,即“流编辑器”。所谓流编辑器,就是指对输入流进行基本文本转换(添加、编辑和删除等操作)的文本编辑器。所谓输入流,就是指给定的文件中的文本以及来自管道的文本。

我们平时习惯了使用可视化的文本编辑器。sed的牛逼之处就在于可以对来自管道等标准输出的文本进行编辑,是一款适用于命令行界面的文本编辑器。

1
sed OPTIONS [addr]X[options] [INPUTFILE...]

sed 命令的运作原理

sed 程序有两个缓冲区,主活动的模式空间(pattern space)和辅助用的保持空间(hold space)。二者在初始化时均为空。

sed 通过在输入的每一行上执行以下循环来进行操作:首先,sed 从输入流中读取一行,删除所有尾随的换行符并将其放在模式空间中。然后执行命令;每个命令可以有一个与之关联的地址:地址是一种条件代码,只有在执行命令之前验证了条件的情况下,命令才会执行。

到达脚本末尾时,除非使用-n选项,否则会把模式空间的内容打印到输出流中,如果删除了尾随的换行符,则将其添加回去。然后,下一个周期开始于下一条输入线。

除非使用特殊命令(如“ D”),否则在两个循环之间删除模式空间。 另一方面,保持空间可在周期之间保持其数据(请参阅命令“ h”,“ H”,“ x”,“ g”,“ G”在两个缓冲区之间移动数据)。

命令格式

1
sed OPTIONS... [SCRIPT] [INPUTFILE...]

OPTION是以“-”开头选项参数。可选项。每个脚本的都可以附带对应的选项参数。

SCRIPT是遵照sed脚本规范的脚本,用以定义进行何种操作。必需项。可以直接输入用单引号'括起的脚本代码,也可以使用编写好的脚本文件。

INPUTFILE就是要编辑的内容。必需项。内容可以是标准输入或是文件,可以添加多个内容。

sed将会对INPUTFILE进行编辑操作,之后将结果打印至输出流。所以如果要用sed编辑某个文件,别忘了采用输出重定向符>>>

常用选项

-n 或 –quiet 或 –silent

关闭模式空间的自动打印。不再把内容打印至屏幕。

-e [SCRIPT] 或 –expression=[SCRIPT]

在-e选项后面可以添加对应的脚本内容。一条sed命令可以包含多个-e和脚本的组合,表示同时执行这些脚本。

-f [SCRIPTFILE] 或 –file=[SCRIPTFILE]

在-f选项后面可以添加对应的脚本文件。一条sed命令可以包含多个-f和脚本文件的组合,表示同时执行这些脚本文件。

-i[FILE] 或 –in-place[=FILE]

加了 -i 之后,sed 就不再把结果打印至标准输出了,而是直接修改该文件的对应位置。这个功能比较凶残,没有备份的话,稍有不慎容易翻车,所以不自信的话还是用先前提到的朴素的方法,使用输出重定向符>>>之类进行操作。

脚本

sed 主要的精髓就在于脚本部分的编写,脚本决定了 sed 的操作行为。

单个操作执行时的脚本结构如下:

1
[addr]X[options]

X 是一个单字母,是 sed 的操作命令,用该命令字符表示 sed 要进行什么操作。

[addr] 是可选的行地址,就是某行文本所处的行数。如果确定了地址,本次 sed 操作将会只应用于该地址上。

[options] 是某些 sed 操作命令所拥有的额外选项

一般来说,多个 sed 脚本可用分号;分隔,同时执行。但有些命令会把;也视作内容的一部分,所以更多时候推荐使用 -e 选项实现多个脚本的执行。

s(substitute,替换)命令

s 命令是最常用也是最复杂的 sed 命令。其表达式为:

1
s/regexp/replacement/flags

s 命令的基本概念很简单:它会试图寻找文本中到每个符合 regexp 所述的匹配项,并将其用 replacement 替换。

下面逐条讲解各个部分。

regexp

正则表达式

关于什么是正则表达式,请上网自行寻找教程。这里给出 Github 上的一个教程。GNU 官网的 sed 使用说明书后半部分也有写。

replacement

flags

可以在s命令脚本的末端添加一个或多个 flag(标志),达成额外效果,下面是标志字符的含义:

  • g:全局标志。对所有符合 regexp 的匹配项应用 replacement 的替换,不再仅对第一个应用。
  • [数字]:
  • p:
  • w 文件名:
  • e:
  • I或i:
  • M或m:

其他重点常用命令

q (quit,退出)

退出 sed 程序而不进行其他操作。在写脚本的时候用这个命令让脚本进入下一步。

q命令只接收单个行地址。比如sed 3q FILENAME就会打印出该文件的前三行后退出sed。

a (append,附加)

在目标地址行后的下一行添加一段文本。如果不为a操作指定匹配内容或者行号,它会应用到每一行。

i (insert,插入)

在目标地址行后的上一行添加一段文本。如果不为i操作指定匹配内容或者行号,它会应用到每一行。

c (change,换行)

用一段文本替换目标地址行。如果不为c操作指定匹配内容或者行号,它会应用到每一行。

d (delete,删除)

删除目标地址行。如果不为d操作指定匹配内容或者行号,它会应用到每一行。(就全删了)

r (read,阅读)

阅读目标文件。

p (print,打印)

打印目标地址行的内容。

地址

在 sed 命令中,通过地址选择要进行处理的行。

通过数字选择地址

可以直接输入单个数字。比如1就是第1行,2就是第2行。

可以输入m~n这样的格式选择地址。这时意思就是从第 m 行开始选择(包括第 m 行),每 n 行选择下一个直到末尾。

还可以使用$选择行,意思是选择输入内容的最后一行。

通过范围选择地址

把两个数字用逗号,分隔,设定范围。比如12,25就是从12行到第25行,包括这两行。

也可以把第二个数字写作+n的格式,其中n是一个数字,比如12,+2就是12到14行,包括这两行。

通过正则表达式选择地址

用两个/括起来,会选择所有符合//内正则匹配式的行的地址。


参考文献

  1. GNU 官网 sed 说明书
  2. SED 简明教程 - CoreShell
  3. 流编辑器 SED 十分钟入门全教程
  4. 模式空间与保持空间
本文由作者按照 CC BY 4.0 进行授权