sed 模式管理

让我们讨论 n 命令,该命令打印模式空间。它将与其他命令结合使用。下面给出的是 n 命令的语法。

[address1[,address2]]n

让我们举个例子。

$sed 'n' 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 

n 命令将打印模式缓冲区的内容,清除模式缓冲区,将下一行提取到模式缓冲区中,并在其上应用命令。

让我们考虑 n 之前的三个SED命令和 n 之后的两个SED命令,如下所示:

Sed command #1 
Sed command #2 
Sed command #3 
n command 
Sed command #4 
Sed command #5

在这种情况下,SED在模式缓冲区上应用前三个命令,清除模式缓冲区,将下一行提取到模式缓冲区中,然后在其上应用第四和第五个命令。

SED提供 x 命令来交换模式和保持缓冲区的内容。以下命令说明了 x 命令。

让我们稍微修改books.txt文件。说,该文件包含书名及其作者姓名。修改后,文件应如下所示:

$cat books.txt

执行上述代码后,您将得到以下输出:

A Storm of Swords 
George R. R. Martin 
The Two Towers 
J. R. R. Tolkien 
The Alchemist 
Paulo Coelho 
The Fellowship of the Ring 
J. R. R. Tolkien 
The Pilgrimage 
Paulo Coelho 
A Game of Thrones 
George R. R. Martin 

让我们交换两个缓冲区的内容。例如,以下示例仅打印作者的姓名。

$sed -n 'x;n;p' books.txt 

执行上述代码后,您将得到以下输出:

George R. R. Martin 
J. R. R. Tolkien 
Paulo Coelho 
J. R. R. Tolkien 
Paulo Coelho 
George R. R. Martin 

现在让我们在打印之前交换缓冲区的内容。猜猜,会发生什么?是的,它会打印书籍的标题。

$sed -n 'x;n;x;p' books.txt 

执行上述代码后,您将得到以下输出:

A Storm of Swords 
The Two Towers 
The Alchemist 
The Fellowship of the Ring 
The Pilgrimage 
A Game of Thrones

h 命令处理保留缓冲区,它将数据从模式缓冲区复制到保持缓冲区,保留缓冲区中的现有数据将被覆盖。请注意, h 命令不会移动数据,它只会复制数据。因此,复制的数据将保留在模式缓冲区中。下面给出的是 h 命令的语法。

[address1[,address2]]h 

以下命令仅打印作者Paulo Coelho的标题。

$sed -n '/Paulo/!h; /Paulo/{x;p}' books.txt 

执行上述代码后,您将得到以下输出:

The Alchemist 
The Pilgrimage

让我们了解以上命令的工作原理。 books.txt的内容采用特定格式。第一行是书名,其后是书的作者。在上面的命令中,"!"用于反转条件,即仅当模式匹配失败时才将行复制到保持缓冲区。花括号{}用于对多个SED命令进行分组

h 命令破坏保留缓冲区的先前内容。为此,SED提供了 H 命令,该命令通过在末尾添加新行来将内容附加到保持缓冲区。 h 和 H 命令之间的唯一区别是,前者覆盖保留缓冲区中的数据,而后者将数据追加到保留缓冲区中。它的语法类似于 h 命令。

[address1[,address2]]H

让我们再举一个例子。这次,不仅打印书名,还打印其作者的姓名。以下示例打印书名及其作者姓名。

$sed -n '/Paulo/!h; /Paulo/{H;x;p}' books.txt 

执行上述代码后,您将得到以下输出:

The Alchemist 
Paulo Coelho 
The Pilgrimage
Paulo Coelho

我们学习了如何将模式缓冲区的内容复制/追加到保持缓冲区。我们还能执行反向函数吗?是的,当然了!为此,SED提供了 g 命令,该命令将数据从保持缓冲区复制到模式缓冲区。复制时,来自模式空间的现有数据将被覆盖。下面给出的是 g 命令的语法。

[address1[,address2]]g

让我们考虑相同的示例-打印书名及其作者。这次,我们将首先打印作者的姓名,并在下一行上打印相应的书名。以下命令显示作者Paulo Coelho的姓名,以及其书名。

$sed -n '/Paulo/!h; /Paulo/{p;g;p}' books.txt 

执行上述代码后,您将得到以下输出:

Paulo Coelho 
The Alchemist 
Paulo Coelho 
The Pilgrimage

同样,我们可以将保持缓冲区的内容附加到模式缓冲区。 SED提供 G 命令,该命令通过在末尾添加新行来将内容附加到模式缓冲区。

[address1[,address2]]G

现在,让我们以前面的示例为例,该示例将作者Paulo Coelhofolol的名字印在书名的后面。要获得相同的输出,请执行以下SED命令。

$sed -n '/Paulo/!h; /Paulo/{G;p}' books.txt

执行上述代码后,您将得到以下输出:

Paulo Coelho 
The Alchemist 
Paulo Coelho 
The Pilgrimage

您可以修改上面的示例以显示其作者之后的书名吗?很简单,只需在 G 命令之前交换缓冲区内容。

$sed -n '/Paulo/!h; /Paulo/{x;G;p}' books.txt

执行上述代码后,您将得到以下输出:

The Alchemist 
Paulo Coelho 
The Pilgrimage 
Paulo Coelho