sed 基本命令

本章介绍了几个有用的SED命令。

Delete命令

SED提供各种命令来操作文本。让我们首先探讨 delete 命令。这是执行删除命令的方式:

[address1[,address2]]d 

address1 和 address2 分别是起始地址和结束地址,可以是行号或模式字符串,这两个参数都是可选的。

注意(,) delete 命令仅从模式缓冲区中删除行,而不会覆盖文件内容。以下示例说明了这一点。

$sed 'd' books.txt 

但是为什么不有输出内容?因为默认情况下SED在每行上运行,但没有输出命令。

下面的示例仅删除第4行。

$sed '4d' 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 
5) The Pilgrimage, Paulo Coelho, 288 
6) A Game of Thrones, George R. R. Martin, 864

此外,SED还使用 逗号(,) 接受 地址范围 。例如,以下示例从2到4删除所有行。

$sed '2, 4 d' books.txt 

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

1) A Storm of Swords, George R. R. Martin, 1216 
5) The Pilgrimage, Paulo Coelho, 288 
6) A Game of Thrones, George R. R. Martin, 864

SED的地址范围不仅限于数字,我们还可以将模式指定为地址,下面的示例删除了作者Paulo Coelho的所有书籍。

$sed '/Paulo Coelho/d' books.txt 

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

1) A Storm of Swords, George R. R. Martin, 1216 
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 

我们还可以使用文本模式指定地址范围。以下示例删除了"Storm"和"Fellowship"之间的所有行。

$sed '/Storm/,/Fellowship/d' books.txt  
5) The Pilgrimage, Paulo Coelho, 288 
6) A Game of Thrones, George R. R. Martin, 864 

Write命令

我们对任何文件执行的重要操作之一就是备份,即我们制作了该文件的另一个副本。 SED提供 write 命令以将模式缓冲区的内容存储在文件中。下面给出的是 write 命令的语法,它与 delete 命令相似。

[address1[,address2]]w file 

在这里(,) address1 和 address2 分别是开始地址和结束参数,这两个参数都是可选的。

在以上语法中(,) w 表示写入命令,而 file 是用于存储内容的文件名。请小心 file 参数,提供文件名后,如果文件名不存在,SED会即时创建一个文件,如果文件名已存在,则SED会覆盖它。

让我们使用SED复制文件。请注意(,) w 和文件之间必须恰好有一个空格。

$sed -n 'w books.bak' books.txt 

我们创建了另一个名为 books.bak的文件。现在,验证两个文件具有相同的内容。

$diff books.txt books.bak  
$echo $?

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

0

 cp 命令执行的操作完全相同。它允许创建一个仅包含源文件中某些行的文件。让我们仅将偶数行存储到另一个文件中。

$sed -n '2~2 w junk.txt' books.txt  
$cat junk.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 

您还可以在write命令中使用 逗号(,) 美元($) 加号(+)运算符。

除此之外,SED还支持使用write命令进行模式匹配。假设您要将各个作者的所有书籍都存储到一个单独的文件中。

$sed -n -e '/Martin/w Martin.txt' -e '/Paulo/w Paulo.txt' -e '/Tolkien/w 
Tolkien.txt' books.txt 

在上面的示例中,我们将每行与一个模式匹配,并将匹配的行存储在特定文件中。这很简单。为了指定多个命令,我们使用了SED命令的 -e 参数。现在让我们使用每个文件包含的内容:

$cat Martin.txt

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

1) A Storm of Swords, George R. R. Martin, 1216 
6) A Game of Thrones, George R. R. Martin, 864

让我们显示文件内容。

$cat Paulo.txt

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

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

让我们显示文件内容。

$cat Tolkien.txt

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

2) The Two Towers, J. R. R. Tolkien, 352 
4) The Fellowship of the Ring, J. R. R. Tolkien, 432 

Append命令

任何文本编辑器最有用的操作之一就是提供附加函数。 SED通过其append命令支持此操作。下面给出了append的语法:

[address]a\
Append text 

让我们在第4行之后附加一个新书条目。下面的示例显示了如何做

$sed '4 a 7) Adultry, Paulo Coelho, 234' 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 
7) Adultry, Paulo Coelho, 234 
5) The Pilgrimage, Paulo Coelho, 288 
6) A Game of Thrones, George R. R. Martin, 864

让我们在文件末尾插入一个文本行。为此,请使用 $ 作为地址。以下示例说明了这一点:

$sed '$a 7) Adultry, Paulo Coelho, 234' 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 
7) Adultry, Paulo Coelho, 234 

除了行号,我们还可以使用文本模式指定地址。例如,以下示例在匹配字符串 The Alchemist 之后追加文本。

$sed '/The Alchemist/a 7) Adultry, Paulo Coelho, 234' 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 
7) Adultry, Paulo Coelho, 234 
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 '/The/a 7) Adultry, Paulo Coelho, 234' books.txt 

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

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

Change 命令

SED提供由c表示的 change 或 replace 命令。此命令有助于用新文本替换现有行。下面给出的是change命令的语法:

[address1[,address2]]c\
Replace text

让我们用其他一些文本代替第三行。

下面给出的是 N 命令的语法。

[address1[,address2]]N

让我们打印以逗号分隔的书名及其作者列表。以下示例说明了这一点。

$sed 'N; s/\n/, /g' 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

像 p 命令一样,我们有一个 P 命令来打印由 N 命令。下面给出的是 P 命令的语法,与 p 命令相似。

[address1[,address2]]P 

在前面的示例中,我们看到 N 命令创建了以换行符分隔的书名及其作者列表。我们仅打印其中的第一部分,即仅打印书名。以下命令对此进行了说明。

$sed -n 'N;P' books.txt

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

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

请注意,在没有 N 的情况下,它的行为与 p 命令相同。以下简单命令说明了这种情况。

$sed -n 'P' 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还提供了 v 命令来检查版本。如果提供的版本大于安装的SED版本,则命令执行失败。请注意,此选项只能在GNU中使用。

下面给出的是 v 命令的语法。

[address1[,address2]]v [version]

首先,找出SED的当前版本。

$sed --version 

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

sed (GNU sed) 4.2.2 

在以下示例中,SED版本大于4.2.2版本,因此SED命令中止其执行。

$sed 'v 4.2.3' books.txt 

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

sed: -e expression #1, char 7: expected newer version of sed

但是,如果提供的版本小于或等于4.2.2,则该命令将按预期工作。

$sed 'v 4.2.2' 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