流编辑器 - 模式缓冲区



我们在任何文件上执行的基本操作之一是显示其内容。为此,我们可以使用 **print** 命令,它打印模式缓冲区的内容。因此,让我们更多地了解模式缓冲区。

首先创建一个包含行号、书籍名称、作者和页数的文件。在本教程中,我们将使用此文件。您可以根据您的方便使用任何文本文件。我们的文本文件将如下所示

[jerry]$ vi books.txt 
1) A Storm of Swords, George R. R. Martin, 1216 
2) The Two Towers, J. R. R. Tolkien, 352 
3) The Alchemist, Paulo Coelho, 197 
4) The Fellowship of the Ring, J. R. R. Tolkien, 432 
5) The Pilgrimage, Paulo Coelho,288 
6) A Game of Thrones, George R. R. Martin, 864

现在,让我们打印文件内容。

[jerry]$ sed 'p' books.txt

执行上述代码后,将产生以下结果。

1) A Storm of Swords, George R. R. Martin, 1216 
1) A Storm of Swords, George R. R. Martin, 1216 
2) The Two Towers, J. R. R. Tolkien, 352 
2) The Two Towers, J. R. R. Tolkien, 352 
3) The Alchemist, Paulo Coelho, 197 
3) The Alchemist, Paulo Coelho, 197 
4) The Fellowship of the Ring, J. R. R. Tolkien, 432 
4) The Fellowship of the Ring, J. R. R. Tolkien, 432 
5) The Pilgrimage, Paulo Coelho, 288 
5) The Pilgrimage, Paulo Coelho, 288 
6) A Game of Thrones, George R. R. Martin, 864 
6) A Game of Thrones, George R. R. Martin, 864

您可能想知道为什么每行都显示了两次。让我们找出原因。

您还记得 SED 的工作流程吗?默认情况下,SED 会打印模式缓冲区的内容。此外,我们在命令部分显式地包含了一个 print 命令。因此每行都打印了两次。但不用担心。SED 有 **-n** 选项来抑制模式缓冲区的默认打印。以下命令说明了这一点。

[jerry]$ sed -n 'p' books.txt 

执行上述代码后,将产生以下结果。

1) A Storm of Swords, George R. R. Martin, 1216 
2) The Two Towers, J. R. R. Tolkien, 352 
3) The Alchemist, Paulo Coelho, 197 
4) The Fellowship of the Ring, J. R. R. Tolkien, 432 
5) The Pilgrimage, Paulo Coelho, 288 
6) A Game of Thrones, George R. R. Martin, 864 

恭喜!我们得到了预期的结果。默认情况下,SED 对所有行进行操作。但是我们可以强制 SED 仅对某些行进行操作。例如,在下面的示例中,SED 仅对第 3 行进行操作。在此示例中,我们在 SED 命令之前指定了一个地址范围。

[jerry]$ sed -n '3p' books.txt 

执行上述代码后,将产生以下结果。

3) The Alchemist, Paulo Coelho, 197 

此外,我们还可以指示 SED 仅打印某些行。例如,以下代码打印第 2 行到第 5 行的所有行。在这里,我们使用了逗号 (,) 运算符来指定地址范围。

[jerry]$ sed -n '2,5 p' books.txt 

执行上述代码后,将产生以下结果。

2) The Two Towers, J. R. R. Tolkien, 352 
3) The Alchemist, Paulo Coelho, 197 
4) The Fellowship of the Ring, J. R. R. Tolkien, 432 
5) The Pilgrimage, Paulo Coelho, 288

还有一个特殊字符美元符号 ($) 表示文件的最后一行。因此,让我们打印文件的最后一行。

[jerry]$ sed -n '$ p' books.txt 

执行上述代码后,将产生以下结果。

6) A Game of Thrones, George R. R. Martin, 864 

但是我们也可以使用美元符号 ($) 来指定地址范围。下面的示例打印从第 3 行到最后一行。

[jerry]$ sed -n '3,$ p' books.txt 

执行上述代码后,将产生以下结果。

3) The Alchemist, Paulo Coelho, 197 4) The Fellowship of the Ring, J. R. R. Tolkien, 432 5) The Pilgrimage, Paulo Coelho, 288 6) A Game of Thrones, George R. R. Martin, 864 

我们学习了如何使用逗号 (,) 运算符来指定地址范围。SED 支持另外两个可以用来指定地址范围的运算符。第一个是加号 (+) 运算符,它可以与逗号 (,) 运算符一起使用。例如,**M,+n** 将打印从行号 **M** 开始的接下来的 **n** 行。听起来令人困惑?让我们用一个简单的例子来检查一下。以下示例打印从第 2 行开始的接下来的 4 行。

[jerry]$ sed -n '2,+4 p' books.txt 

执行上述代码后,将产生以下结果。

2) The Two Towers, J. R. R. Tolkien, 352 
3) The Alchemist, Paulo Coelho, 197 
4) The Fellowship of the Ring, J. R. R. Tolkien, 432 
5) The Pilgrimage, Paulo Coelho, 288 
6) A Game of Thrones, George R. R. Martin, 864 

或者,我们也可以使用波浪号 (~) 运算符指定地址范围。它使用 **M~n** 格式。它表示 SED 应该从行号 M 开始并处理每第 n 行。例如,**50~5** 匹配行号 50、55、60、65 等。让我们仅打印文件中的奇数行。

[jerry]$ sed -n '1~2 p' books.txt 

执行上述代码后,将产生以下结果。

1) A Storm of Swords, George R. R. Martin, 1216 
3) The Alchemist, Paulo Coelho, 197 
5) The Pilgrimage, Paulo Coelho, 288

以下代码仅打印文件中的偶数行。

[jerry]$ sed -n '2~2 p' books.txt 

执行上述代码后,将产生以下结果。

2) The Two Towers, J. R. R. Tolkien, 352 
4) The Fellowship of the Ring, J. R. R. Tolkien, 432 
6) A Game of Thrones, George R. R. Martin, 864 
广告