sed 工作流程
对于会的人来说,sed 极其简单,对于不会的人来说,sed 简直难如登天。
那是什么原因导致了两种极端?
想想,我们为什么如此的胆小,如此的担心受怕?
面对未知的事物,我们从来不敢越雷池一步,但对于会的已知的,我们却易如反掌。
是什么原因导致了两者的不同?
这个问题困惑我好久,直到有一天,我发现,对于会的已知的,我基本都知道它们是怎么工作的!
那么,对于 sed,如果我们要熟练掌握,就必须知道它是怎么工作的,也就是它的工作流程。
sed 命令语法格式
sed 命令的语法格式如下
sed [option] [sed-command] [input-file]
总的来说 sed 命令主要由四部分构成
sed
关键字[option]
命令行选项,用于改变 sed 的工作流程。[sed-command]
是具体的 sed 命令[input-file]
输入数据,如果不指定,则默认从标准输入中读取。
sed 工作流程
如果你想成为一个 sed 专家,你必须知道 sed 的内部是如何工作的。
sed 的工作流程,说起来真的很简单:
读取行 -> 执行 -> 显示 -> 读取行 -> 执行 -> 显示 -> .... -> 读取行 -> 执行 -> 显示
如果用一张图画出来,大概就是下面这个样子
不要被这张图吓到,其实它的流程真的像上面说的 读取行 -> 执行 -> 显示
循环。
-
读取行
sed 从输入流 (文件、管道、标准输入流)中读取 一行 并存储在名叫
pattern buffer
的内部缓冲区中。sed 是行文字处理器。每次只会读取一行。
sed 内部会有一个计数器,记录着当前已经处理多少行,也就是当前行的行号。
-
执行
按照 sed 命令定义的顺序依次应用于刚刚读取的 一行 数据。
默认情况下,sed 一行一行的处理所有的输入数据。但如果我们指定了行号,则只会处理指定的行。
-
显示
把经过 sed 命令处理的数据发送到输出流(文件、管道、标准输出)。并同时清空
pattern buffer
缓冲区。 -
上面上个流程一直循环,直到输入流中的数据全部处理完成。
注意事项
整个流程看似简单,有几个知识点需要注意:
-
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.twle.cn 3) I am a no-work-men 4) I am so handsome
第一个 sed 命令,我们显示 data.txt 文件的所有内容。也就是使用 sed 命令模拟 cat 命令。
[www.twle.cn]$ cat data.txt 1) I am studing sed 2) I am www.twle.cn 3) I am a no-work-men 4) I am so handsome
输出源文件的内容并不需要任何 sed 语句,因此可以直接 ''
。
模拟 cat 命令的 sed 命令为 sed '' data.txt
[www.twle.cn]$ sed '' data.txt 1) I am studing sed 2) I am www.twle.cn 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 的工作流程
-
首先从输入文件
data.txt
中读取一行,也就是1) I am studing sed
。并存储在pattern buffer
缓冲区中。 -
然后将
pattern buffer
中的数据,也就是1) I am studing sed
应用于每一个 sed 语句''
。因为我们的 sed 语句为空,也就是不对
pattern buffer
中的数据做任何处理。 -
把处理后的数据保存一份到
hold buffer
中。 -
最后把处理后的数据写入输出流,默认情况下是 标准输出,也就是打印
1) I am studing sed
。 同时删除pattern buffer
缓冲区。 -
循环重复上面的 1 2 3 4 流程。
是不是很简单 ?
从标准输入中读取数据
如果我们没有提供输入文件,那么 sed 默认会冲标准输入中读取数据。
[www.twle.cn]$ sed ''
运行上面的命令,会显示光标,等带我们的输入。
你可以随意输入一些字符,比如
简单教程 简单编程
当我们按下回车键,sed 会默认读取刚刚输入的行,然后显示出来
简单教程 简单编程
然后继续等待你输入下一行
如果要退出 sed 输入会话可以按下组合键 ctrl-D (^D)
。