Sed - 模式缓冲区

  • 简述

    我们对任何文件执行的基本操作之一是显示其内容。为此,我们可以使用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 打印模式缓冲区的内容。此外,我们在命令部分中明确包含了一个打印命令。因此,每行打印两次。但别担心。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 的所有行。这里我们使用了 comma(,) 运算符来指定地址范围。
    
    [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
    
    还有一个特殊字符 Dollar($) 代表文件的最后一行。所以让我们打印文件的最后一行。
    
    [jerry]$ sed -n '$ p' books.txt 
    
    执行上述代码时,会产生如下结果。
    6) A Game of Thrones, George R. R. Martin, 864 
    
    但是我们也可以使用 Dollar($) 字符来指定地址范围。下面的示例从第 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将打印下一个n从行号开始的行M. 听起来很混乱?让我们用一个简单的例子来检查一下。以下示例从第 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(th) 行。例如,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