Sed教程(三):模式缓冲区、模式范围

时间:2022-09-08 15:29:08

我们对任何文件进行基本操作,显示其内容。为了达到这个目的,我们可以用打印的模式缓冲区的打印命令。本教程将介绍更多的模式缓冲区,以及如何打印使用相关模式缓冲区不同运算符的文件的内容。

考虑一下我们有一个文本文件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 p 命令

我们可以用Sed 'p'命令来打印指定文件的内容。下面是一个简单的命令来打印文件 books.txt 的内容。

[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打印模式缓冲区的内容。此外,我们已明确地接入命令部分 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只在某些行上使用。例如,在下面的例子中,sed只运行在第三行。在这个例子中,我们指定 sed 命令前一个地址范围。

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

当执行上面的代码,就会产生下面的结果。

3) The Alchemist, Paulo Coelho, 197 

Sed comma 命令

下面的代码打印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

Sed $ 运算符

我们可以使用美元符号$运算符来打印该文件的最后一行,如下所示:

[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 加操作

sed的加号(+)运算符可以用来与逗号(,)运算符。例如M,+ 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

Sed 波浪线运算符

或者,我们也可以使用波浪符号(〜)运算符指定的地址范围。它采用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




本教程介绍如何sed处理一个模式范围。模式范围可以是一个简单的文本或复杂的正则表达式。我们将开始使用下列内容的文本文件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

下面的例子打印的作者所有书籍 Paulo Coelho

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

执行上面的代码,会得到如下结果:

3) The Alchemist, Paulo Coelho, 197 
5) The Pilgrimage, Paulo Coelho, 288

Sed通常运行在每一行,并只打印那些符合使用模式的给定条件的行。

我们还可以将一个模式范围,地址范围。下面的例子打印起始行具有Alchemist 的第一行匹配,直到第五行。

[jerry]$ sed -n '/Alchemist/, 5 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

可以使用美元符号($)发现的模式第一次出现后打印的所有行。下面的示例查找字符串Fellowship的第一次出现,并立即打印该文件中的其余行

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

执行上面的代码,会得到如下结果:

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

也可以指定多个模式范围使用逗号(,)运算符。下面的例子打印所有模式 Two 和 Pilgrimage 之间存在的行。 

[jerry]$ sed -n '/Two/, /Pilgrimage/ 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

此外,我们还可以在模式范围使用的加号(+)运算。下面的例子中发现模式Two第一次出现,并打印它之后的下一个4行。

[jerry]$ sed -n '/Two/, +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

在这里,只给出了几个例子来熟悉sed。可以自己结合上面例子写几个例子试试。


from: http://www.yiibai.com/sed/sed_useful_recipes.html