- Sed 教程
- Sed - 首页
- Sed - 概述
- Sed - 环境
- Sed - 工作流程
- Sed - 基本语法
- Sed - 循环
- Sed - 分支
- Sed - 模式缓冲区
- Sed - 模式范围
- Sed - 基本命令
- Sed - 特殊字符
- Sed - 字符串
- Sed - 模式管理
- Sed - 正则表达式
- Sed - 有用技巧
- Sed 有用资源
- Sed - 快速指南
- Sed - 有用资源
- Sed - 讨论
流编辑器 - 模式管理
我们已经讨论了模式缓冲区和保持缓冲区的使用。在本章中,我们将进一步探讨它们的用法。让我们讨论一下n命令,它打印模式空间的内容。它将与其他命令结合使用。以下是n命令的语法。
[address1[,address2]]n
让我们举个例子。
[jerry]$ 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命令,之后有两个SED命令,如下所示
Sed command #1 Sed command #2 Sed command #3 n command Sed command #4 Sed command #5
在这种情况下,SED将在模式缓冲区上应用前三个命令,清除模式缓冲区,将下一行读取到模式缓冲区,然后在其上应用第四个和第五个命令。这是一个非常重要的概念。如果没有清楚地理解这一点,请不要继续。
保持缓冲区保存数据,但是SED命令不能直接在保持缓冲区上应用。因此,我们需要将保持缓冲区的数据带入模式缓冲区。SED提供x命令来交换模式缓冲区和保持缓冲区的内容。以下命令演示了x命令。
让我们稍微修改一下books.txt文件。假设该文件包含书名及其作者姓名。修改后,文件应如下所示
[jerry]$ 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
让我们交换两个缓冲区的内容。例如,下面的例子只打印作者的姓名。
[jerry]$ 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将第一行,即《A Storm of Swords》读取到模式缓冲区。
x命令将此行移动到保持缓冲区。
n将下一行,即George R. R. Martin读取到模式缓冲区。
控制权传递到n命令后面的命令,该命令打印模式缓冲区的内容。
此过程重复,直到文件结束。
现在让我们在打印之前交换缓冲区的内容。猜猜会发生什么?是的,它打印书名。
[jerry]$ 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的书名。
[jerry]$ sed -n '/Paulo/!h; /Paulo/{x;p}' books.txt
执行上述代码后,您将得到以下结果
The Alchemist The Pilgrimage
让我们了解一下上述命令是如何工作的。books.txt的内容遵循特定的格式。第一行是书名,后面跟着书的作者。在上面的命令中,“!”用于反转条件,即只有在模式匹配不成功时才将行复制到保持缓冲区。花括号{}用于组合多个SED命令
在命令的第一次遍历中,SED将第一行,即《A Storm of Swords》读取到模式缓冲区,并检查它是否包含模式Paulo。由于模式匹配不成功,它将此行复制到保持缓冲区。现在模式缓冲区和保持缓冲区都包含相同的行,即《A Storm of Swords》。在第二步中,它检查该行是否包含模式Paulo。由于模式不匹配,它什么也不做。
在第二次遍历中,它将下一行George R. R. Martin读取到模式缓冲区,并应用相同的步骤。对于接下来的三行,它执行相同的操作。在第五次遍历结束时,两个缓冲区都包含《The Alchemist》。在第六次遍历开始时,它读取行Paulo Coelho,并且由于模式匹配,它不会将此行复制到保持缓冲区。因此,模式缓冲区包含Paulo Coelho,保持缓冲区包含《The Alchemist》。
此后,它检查模式缓冲区是否包含模式Paulo。由于模式匹配成功,它将模式缓冲区的内容与保持缓冲区的内容交换。现在模式缓冲区包含《The Alchemist》,保持缓冲区包含Paulo Coelho。最后,它打印模式缓冲区的内容。相同的步骤应用于模式《The Pilgrimage》。
h命令会销毁保持缓冲区中的先前内容。这并不总是可取的,因为有时我们需要保留内容。为此,SED提供了H命令,它通过在末尾添加新行来将内容追加到保持缓冲区。h和H命令之间的唯一区别是,前者覆盖保持缓冲区中的数据,而后者将数据追加到保持缓冲区。它的语法与h命令类似。
[address1[,address2]]H
让我们再举一个例子。这次,我们不仅打印书名,还打印作者姓名。以下示例打印书名及其作者姓名。
[jerry]$ 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的姓名,然后是其书名。
[jerry]$ sed -n '/Paulo/!h; /Paulo/{p;g;p}' books.txt
执行上述代码后,您将得到以下结果
Paulo Coelho The Alchemist Paulo Coelho The Pilgrimage
第一个命令保持不变。在第五次遍历结束时,两个缓冲区都包含《The Alchemist》。在第六次遍历开始时,它读取行Paulo Coelho,并且由于模式匹配,它不会将此行复制到保持缓冲区。因此,模式空间包含Paulo Coelho,保持空间包含《The Alchemist》。
此后,它检查模式空间是否包含模式Paulo。由于模式匹配成功,它首先打印模式空间的内容,即Paulo Coelho,然后它将保持缓冲区复制到模式缓冲区。因此,模式缓冲区和保持缓冲区都包含《The Alchemist》。最后,它打印模式缓冲区的内容。相同的步骤应用于模式《The Pilgrimage》。
类似地,我们可以将保持缓冲区的内容追加到模式缓冲区。SED提供G命令,它通过在末尾添加新行来将内容追加到模式缓冲区。
[address1[,address2]]G
现在让我们来看之前的示例,该示例打印作者Paulo Coelho的姓名及其书名。要实现相同的结果,请执行以下SED命令。
[jerry]$ sed -n '/Paulo/!h; /Paulo/{G;p}' books.txt
执行上述代码后,您将得到以下结果
Paulo Coelho The Alchemist Paulo Coelho The Pilgrimage
您可以修改上面的示例以显示书名及其作者吗?很简单,只需在G命令之前交换缓冲区内容即可。
[jerry]$ sed -n '/Paulo/!h; /Paulo/{x;G;p}' books.txt
执行上述代码后,您将得到以下结果
The Alchemist Paulo Coelho The Pilgrimage Paulo Coelho