04、sed 工作流程

对于会的人来说,sed 极其简单,对于不会的人来说,sed 简直难如登天。

那是什么原因导致了两种极端?

想想,我们为什么如此的胆小,如此的担心受怕?

面对未知的事物,我们从来不敢越雷池一步,但对于会的已知的,我们却易如反掌。

是什么原因导致了两者的不同?

这个问题困惑我好久,直到有一天,我发现,对于会的已知的,我基本都知道它们是怎么工作的!

那么,对于 sed,如果我们要熟练掌握,就必须知道它是怎么工作的,也就是它的工作流程。

sed 命令语法格式

sed命令的语法格式如下

sed [option] [sed-command] [input-file]

总的来说 sed 命令主要由四部分构成

1、 sed关键字;
2、 [option]命令行选项,用于改变sed的工作流程;
3、 [sed-command]是具体的sed命令;
4、 [input-file]输入数据,如果不指定,则默认从标准输入中读取;

sed 工作流程

如果你想成为一个 sed 专家,你必须知道 sed 的内部是如何工作的。

sed的工作流程,说起来真的很简单:

读取行 -> 执行 -> 显示 -> 读取行 -> 执行 -> 显示 -> .... -> 读取行 -> 执行 -> 显示

不要被这张图吓到,其实它的流程真的像上面说的 读取行 ->执行 -> 显示 循环。

1、 读取行

sed 从输入流 (文件、管道、标准输入流)中读取 一行 并存储在名叫 pattern buffer 的内部缓冲区中。

sed 是行文字处理器。每次只会读取一行。

sed 内部会有一个计数器,记录着当前已经处理多少行,也就是当前行的行号。

2、 执行

按照 sed 命令定义的顺序依次应用于刚刚读取的 一行 数据。

默认情况下,sed 一行一行的处理所有的输入数据。但如果我们指定了行号,则只会处理指定的行。

3、 显示

把经过 sed 命令处理的数据发送到输出流(文件、管道、标准输出)。并同时清空 pattern buffer 缓冲区。

4、 上面上个流程一直循环,直到输入流中的数据全部处理完成;

注意事项

整个流程看似简单,有几个知识点需要注意:

  • pattern buffer 缓冲区是 sed 在内存上开辟的一个私有的存储区域。

内存的特性,会导致关闭命令行或关机数据就没了。

  • 默认情况下,sed 命令只会处理 pattern buffer 缓冲区中的数据,且并不会将处理后的数据保存到源文件中。

也就是说,sed 默认并不会修改源文件。

但 GNU SED 提供提供了一种方式用于修改 源文件。方式就是传递 -i 选项。

至于具体的如何处理,我们会在后面的章节中介绍。

  • sed 还在内存上开辟了另一个私有的缓冲区 hold buffer 用于保存处理后的数据以供以后检索。

每一个周期执行结束,sed 会清空 pattern buffer 缓冲区的内容,但 hold buffer 缓冲区的内容并不会清空。

hold buffer 缓冲区用于存储处理后数据,sed 命令并不会对这里的数据处理。

这样,当 sed 需要之前处理后的数据时,可以随时从 hold buffer 缓冲区读取。

  • sed 程序执行前,模式 pattern 和 hold buffer 缓冲区都是空的。
  • 如果我们没有传递任何输入文件,sed 默认会从 标准输入 中读取数据。
  • sed 可以指定只处理输入数据中的行范围。默认情况下是全部行,因此会依次处理每一行。

范例

上面的流程和注意事项说着说着有点复杂的样子。

别担心,sed 真的很简单的。

下面我们就通过几个简单的 sed 命令来梳理下 sed 的工作流程。

首先在当前目录下 (随便哪个目录,只要终端当前在这个目录下就可以)创建一个文件 data.txt 并输入以下内容

1) I am studing sed
2) I am www.ddkk.com
3) I am a no-work-men
4) I am so handsome

第一个sed 命令,我们显示 data.txt 文件的所有内容。也就是使用 sed 命令模拟 cat 命令。

[www.ddkk.com]$ cat data.txt
1) I am studing sed
2) I am www.ddkk.com
3) I am a no-work-men
4) I am so handsome

输出源文件的内容并不需要任何 sed 语句,因此可以直接 ''。

模拟cat 命令的 sed 命令为 sed '' data.txt

[www.ddkk.com]$ sed '' data.txt
1) I am studing sed
2) I am www.ddkk.com
3) I am a no-work-men
4) I am so handsome

对照着sed 命令的语法格式

sed [option] [sed-command] [input-file]

  • data.txt 对应着 [input-file]。用于提供输入数据。
  • '' 对应着 [sed-command] 为具体的 sed 语句。

'' 并不是 [option]。[option] 类似于 -i 或 --i xxx 等格式。

我们就用这个简单的 sed 命令来解释下 sed 的工作流程

1、 首先从输入文件data.txt中读取一行,也就是1)Iamstudingsed并存储在patternbuffer缓冲区中;
2、 然后将patternbuffer中的数据,也就是1)Iamstudingsed应用于每一个sed语句'';

因为我们的 sed 语句为空,也就是不对 pattern buffer 中的数据做任何处理。

3、 把处理后的数据保存一份到holdbuffer中;
4、 最后把处理后的数据写入输出流,默认情况下是标准输出,也就是打印1)Iamstudingsed同时删除patternbuffer缓冲区;
5、 循环重复上面的1234流程;

是不是很简单 ?

从标准输入中读取数据

如果我们没有提供输入文件,那么 sed 默认会冲标准输入中读取数据。

[www.ddkk.com]$ sed ''

运行上面的命令,会显示光标,等带我们的输入。

你可以随意输入一些字符,比如

DDKK.COM 弟弟快看,程序员编程资料站 DDKK.COM 弟弟快看,程序员编程资料站

当我们按下回车键,sed 会默认读取刚刚输入的行,然后显示出来

DDKK.COM 弟弟快看,程序员编程资料站 DDKK.COM 弟弟快看,程序员编程资料站

然后继续等待你输入下一行

如果要退出 sed 输入会话可以按下组合键 ctrl-D (^D)。