学习使用 Sed 文本编辑器
sed

> 
> Sed 缺少通常的文本框，而是按照用户的命令直接写入到文件上。
> 
> 
> 


![](/data/attachment/album/202101/07/002353st8vgivu78yzp77v.jpg)


`sed` 命令是为 AT&T 最初的 Unix 操作系统第 7 版创建的，此后，可能每一个 Unix 和 Linux 操作系统都包含了它。`sed` 应用程序是一个 *流编辑器*，与文本编辑器不同的是，它不会打开一个视觉缓冲区，将文件的数据加载到其中进行处理。相反，它根据在终端输入的命令或脚本中的一系列命令，逐行对文件进行操作。


### 安装


如果你使用的是 Linux、BSD 或 macOS，那么你已经安装了 GNU 或 BSD 版的 `sed`。这是两个不同的原始 `sed` 命令的重新实现，虽然它们很相似，但也有一些小的区别。GNU `sed` 通常被认为是功能最丰富的 `sed`，而且它在这些平台上都可以广泛使用。


如果你找不到 GNU `sed`（在非 Linux 系统上通常被称为 `gsed`），那么你可以[从 GNU 网站上下载它的源代码](http://www.gnu.org/software/sed/)。安装 GNU `sed` 的好处是，可以使用它的额外功能，但它也可以被限制为只符合 `sed` 的 [POSIX](https://opensource.com/article/19/7/what-posix-richard-stallman-explains) 规范，如果你需要移植性的话。


在 Windows 上，你可以用 [Chocolatey](https://opensource.com/article/20/3/chocolatey) 来[安装](https://chocolatey.org/packages/sed) GNU `sed`。


### Sed 如何工作


`sed` 应用程序一次只处理一行。因为它没有视觉显示，所以它在内存中创建了一个模式空间：一个包含输入流的当前行的空间（去掉任何尾部的换行符）。一旦填充了模式空间，你对 `sed` 的指令就会被执行。有时你的指令是有条件的，有时是无条件的，所以这些指令的结果取决于你如何使用 `sed`。


当命令结束时，`sed` 会将模式空间的内容打印到输出流中。默认的输出流是**标准输出**，但可以将其重定向到一个文件，甚至使用 `--in-place=.bak` 选项重定向到同一个文件中。


然后再从下一个输入行开始循环。


`sed`命令的语法是：



```
$ sed --options [optional SCRIPT] [INPUT FILE or STREAM]

```

#### 找到你要编辑的内容


在可视化编辑器中，你通常不需要考虑太多，就能在文本文件中找到你想要修改的内容。你的眼睛（或屏幕阅读器）会扫描文本，找到你想改变的单词或你想插入或删除文本的地方，然后你就可以开始输入了。而 `sed` 没有交互模式，所以你需要告诉它必须满足什么条件才能运行特定的命令。


在这些例子中，假设一个名为 `example.txt` 的文件包含了这样的文字：



```
hello
world
This is line three.
Here is the final line.

```

#### 行号


指定行号告诉 `sed` 只对文件中的那一行进行操作。


例如，下面这条命令选择文件的第 1 行并打印出来。因为 `sed` 在处理后的默认操作也是打印一行到**标准输出**，这样做的效果就是重复第一行：



```
$ sed '1p' example.txt
hello
hello
world
This is line three.
Here is the final line.

```

你也可以步进式指定行号。例如，`1~2` 表示每两行选择一行（“从第一行开始每两行选择一行”）。指令 `1~3` 表示从第一行开始，每三行选择一行：



```
$ sed '1p' example.txt
hello
hello
world
This is line three.
Here is the final line.
Here is the final line.

```

#### 行定位


你可以通过使用 `$` 作为选择器，只对文件的最后一行进行操作：



```
$ sed '$p' example.txt
hello
world
This is line three.
Here is the final line.
Here is the final line.

```

在 GNU `sed` 中，你可以选择多行（例如，`sed '1,$p'` 打印第一行和最后一行）。


#### 反转


任何数字或位置的选择，你都可以用感叹号（`!`）字符反转。下面这将选择除第一行以外的所有行：



```
$ sed '1!p' example.txt
hello
world
world
This is line three.
This is line three.
Here is the final line.
Here is the final line.

```

#### 模式匹配


你可以把模式匹配想象成文字处理器或浏览器中的**查找**操作。你提供一个词（一个 *模式*），然后选择了结果。模式匹配的语法是 `/pattern/`：



```
$ sed '/hello/p' example.txt
hello
hello
world
This is line three.
Here is the final line.
$ sed '/line/p' example.txt
hello
world
This is line three.
This is line three.
Here is the final line.
Here is the final line.

```

### 用 Sed 编辑


一旦你找到了你要编辑的内容，你就可以执行你想要的任何操作。你可以用 `sed` 中的命令来执行编辑。`sed` 中的命令不是 `sed` 命令本身。如果这样说有帮助的话，可以把它们看作是“动作”或“动词”或“指令”。


`sed` 中的命令是单个字母，例如前面例子中使用的**打印**命令的 `p`。它们一开始可能很难记忆，但和所有事情一样，你会随着练习而了解它们。


#### p 代表打印


`p` 指令打印当前模式空间中的任何内容。


#### d 用于删除


`d` 指令删除模式空间：



```
$ sed '$d' example.txt
hello
world
This is line three.
$ sed '1d' example.txt
world
This is line three.
Here is the final line.

```

#### s 用于搜索和替换


`s` 命令搜索一个模式并将其替换为其他东西。这可能是 `sed` 最流行和最随意的用法，而且它通常是用户学习的第一个（有时也是唯一的）`sed` 命令。几乎可以肯定它是文本编辑中最有用的命令：



```
$ sed 's/world/opensource.com/' example.txt
hello
opensource.com
This is line three.
Here is the final line.

```

在你的替换文本中，也可以使用一些特殊的功能。例如，`\L` 将替换文本转换为小写，`\l` 则只转换下一个字符。还有其他一些功能，列在 `sed` 文档中（你可以用 `info sed` 命令查看）。


替换子句中的特殊字符 `&` 指的是匹配到的模式：



```
$ sed 's/is/\U&/' example.txt
hello
world
ThIS is line three.
Here IS the final line.

```

你也可以通过特殊的标志来影响 `s` 如何处理它找到的内容。`g`（应该是指 *全局*）标志告诉 `s` 对行上找到的所有匹配项进行替换，而不仅仅是第一个匹配项：



```
$ sed 's/is/\U&/g' example.txt
hello
world
ThIS IS line three.
Here IS the final line.

```

其他重要的标志还包括用一个数字来表示要影响第几个出现的匹配模式：



```
$ sed 's/is/\U&/2' example.txt
hello
world
This IS line three.
Here is the final line.

```

`w` 标志，后面跟着一个文件名，\_只有\_在有变化的情况下，才会将匹配的行写入文件：



```
$ sed 's/is/\U&/w sed.log' example.txt
hello
world
ThIS is line three.
Here IS the final line.
$ cat sed.log
ThIS is line three.
Here IS the final line.

```

标志可以组合：



```
$ sed 's/is/\U&/2w sed.log' example.txt
hello
world
This IS line three.
Here is the final line.
$ cat sed.log
This IS line three.

```

### 脚本


有很多很棒的网站都有 `sed` “单行脚本”，它们给你提供了面向任务的 `sed` 命令来解决常见的问题。然而，自己学习 `sed` 可以让你写出自己的单行脚本，而且这些单行脚本可以根据你的具体需求来定制。


`sed` 的脚本可以在终端中写成一行，也可以保存到文件中，然后用 `sed` 本身执行。我倾向于把小脚本写成一个命令，因为我发现自己在现实生活中很少重复使用 `sed` 命令。当我写一个 `sed` 脚本时，通常都是针对一个文件的。例如，在写完这篇文章的初稿后，我用 `sed` 来规范 “sed” 的大小写，而这是我可能永远也不会再做的任务。


你可以向 `sed` 发出一系列不同的命令，用分号（`;`）分开。



```
$ sed '3t ; s/line/\U&/' example.txt
hello
world
This is LINE three.
This is the final line.

```

### 带括号的范围改变


你也可以用大括号（`{}`）限制哪些结果受到影响。当你将 `sed` 命令用大括号括起来时，它们只适用于特定的选择。例如，“line” 字出现在样本文本的两行中。你可以通过声明所需的匹配条件（`$` 表示最后一行），并将你希望执行的 `s` 命令放在紧随其后的括号中，强制 `sed` 只影响最后一行：



```
$ sed '$ {s/line/\U&/}' example.txt
hello
world
This is line three.
This is the final LINE.

```

### 学习 Sed


你可以用 `sed` 做的事情比本文所解释的多得多。我甚至还没有涉及到分支（`b`）、测试（`t`）、保留空格（`H`）和许多其他功能。就像 [ed](https://opensource.com/article/20/12/gnu-ed) 一样，`sed` 可能不是你要用来创建文档的文本编辑器，甚至不是你需要做的每一个脚本任务中使用的文本编辑器，但它是你作为 POSIX 用户的一个强大的选择。学习 `sed` 命令的结构以及如何编写简短的脚本可以快速修改大量的文本。阅读 GNU `sed` 的`info` 页面，或者 BSD `sed` 的手册页，看看 `sed` 能为你做什么。




---


via: <https://opensource.com/article/20/12/sed>


作者：[Seth Kenlon](https://opensource.com/users/seth) 选题：[lujun9972](https://github.com/lujun9972) 译者：[wxy](https://github.com/wxy) 校对：[wxy](https://github.com/wxy)


本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


OK
Created for version 7 of AT&T’s original Unix operating system, the `sed`

command has been included with probably every Unix and Linux OS since. The `sed`

application is a *stream editor*, and unlike a text editor it doesn’t open a visual buffer into which a file’s data is loaded for processing. Instead, it operates on a file, line by line, according to either a command typed into a terminal or a series of commands in a script.

## Installing


If you’re using Linux, BSD, or macOS, then you already have GNU or BSD `sed`

installed. These are two unique reimplementations of the original `sed`

command, and while they’re similar, there can be minor differences. GNU `sed`

is generally regarded to be the most feature-rich `sed`

out there, and it’s widely available on any of these platforms.

If you can’t find GNU `sed`

(often called `gsed`

on non-Linux systems), then you can [download its source code from the GNU website](http://www.gnu.org/software/sed/). The nice thing about having GNU `sed`

installed is that it can be used for its extra functions, but it can also be constrained to conform to just the [POSIX](https://opensource.com/article/19/7/what-posix-richard-stallman-explains) specifications of `sed`

, should you require portability.

On Windows, you can [install](https://chocolatey.org/packages/sed) GNU `sed`

with [Chocolatey](https://opensource.com/article/20/3/chocolatey).

## How Sed works

The `sed`

application works on one line at a time. Because it has no visual display, it creates a pattern space—a space in memory containing the current line from the input stream (with any trailing newline character removed). Once the pattern space is populated, your instructions to `sed`

are executed. Sometimes your commands are conditional, and other times they are absolute, so the results of these commands depend on how you’re using `sed`

.

When the end of commands is reached, `sed`

prints the contents of the pattern space to the output stream. The default output stream is **stdout**, but it can be redirected to a file or even back into the same file using the `--in-place=.bak`

option.

Then the cycle begins again with the next input line.

The syntax for the `sed`

command is:

`$ sed --options [optional SCRIPT] [INPUT FILE or STREAM]`


### Finding what you want to edit

In a visual editor, you usually locate what you want to change in a text file without thinking much about it. Your eye (or screen reader) scans the text, finds the word you want to change or the place you want to insert or remove text, and then you just start typing. There is no interactive mode for `sed`

, though, so you must tell it what conditions must be met for it to run specific commands.

For these examples, assume that a file called `example.txt`

contains this text:

```
hello
world
This is line three.
Here is the final line.
```


### Line number

Specifying a line number tells `sed`

to operate only on that specific line in the file.

For instance, this command selects line 1 of a file and prints it. Because `sed`

’s default action after processing is also to print a line to **stdout**, this has the effect of duplicating the first line:

```
$ sed ‘1p’ example.txt
hello
hello
world
This is line three.
Here is the final line.
```


You can specify line numbers in steps, too. For instance, `1~2`

indicates that every 2 lines are selected ("select every second line starting with the first"). The instruction `1~3`

means to select every third line after the first:

```
$ sed ‘1p’ example.txt
hello
hello
world
This is line three.
Here is the final line.
Here is the final line.
```


### Line position

You can operate only on the last line of a file by using `$`

as a selector:

```
$ sed ‘$p’ example.txt
hello
world
This is line three.
Here is the final line.
Here is the final line.
```


In GNU `sed`

, you can select more than one line (`sed '1,$p'`

prints the first and final line, for example).

### Negation

Any selection by number or position, you can invert with the exclamation mark (`!`

) character. This selects all lines *except* the first line:

```
$ sed ‘1!p’ example.txt
hello
world
world
This is line three.
This is line three.
Here is the final line.
Here is the final line.
```


### Pattern matching

You can think of a pattern match as a **find** operation in a word processor or a browser. You provide a word (a *pattern*), and the results are selected. The syntax for a pattern match is `/pattern/`

.

```
$ sed ‘/hello/p’ example.txt
hello
hello
world
This is line three.
Here is the final line.
$ sed ‘/line/p’ example.txt
hello
world
This is line three.
This is line three.
Here is the final line.
Here is the final line.
```


## Editing with Sed

Once you’ve found what you want to edit, you can perform whatever action you want. You perform edits with `sed`

with commands. Commands in `sed`

are different from the `sed`

command itself. If it helps, think of them as "actions" or "verbs" or "instructions."

Commands in `sed`

are single letters, such as the `p`

for **print** command used in previous examples. They can be difficult to recall at first, but as with everything, you get to know them with practice.

### p for print

The `p`

instruction prints whatever is currently held in pattern space.

### d for delete

The `d`

instruction deletes the pattern space.

```
$ sed ‘$d’ example.txt
hello
world
This is line three.
$ sed ‘1d’ example.txt
world
This is line three.
Here is the final line.
```


### s for search and replace

The `s`

command searches for a pattern and replaces it with something else. This is probably the most popular and casual use for `sed`

, and it’s often the first (and sometimes the only) `sed`

command a user learns. It’s almost certainly the most useful command for text editing.

```
$ sed ‘s/world/opensource.com/’
hello
opensource.com
This is line three.
Here is the final line.
```


There are special functions you can use in your replacement text, too. For instance, `\L`

transforms the replacement text to lowercase and `\l`

does the same for just the next character. There are others, which are listed in the `sed`

documentation (you can view that with the `info sed`

command).

The special character `&`

in the replacement clause refers to the matched pattern:

```
$ sed ‘s/is/\U&/’ example.txt
hello
world
ThIS is line three.
Here IS the final line.
```


You can also pass special flags to affect how `s`

processes what it finds. The `g`

(for *global*, presumably) flag tells `s`

to apply the replacement to all matches found on the line and not just the first match:

```
$ sed ‘s/is/\U&/g’ example.txt
hello
world
ThIS IS line three.
Here IS the final line.
```


Other important flags include a number to indicate which occurrence of a matched pattern to affect:

```
$ sed ‘s/is/\U&/2’ example.txt
hello
world
This IS line three.
Here is the final line.
```


The `w`

flag, followed by a filename, writes a matched line to a file *only if* a change is made:

```
$ sed ‘s/is/\U&/w sed.log’ example.txt
hello
world
ThIS is line three.
Here IS the final line.
$ cat sed.log
ThIS is line three.
Here IS the final line.
```


Flags can be combined:

```
$ sed ‘s/is/\U&/2w sed.log’ example.txt
hello
world
This IS line three.
Here is the final line.
$ cat sed.log
This IS line three.
```


## Scripts

There are lots of great sites out there with `sed`

"one-liners." They give you task-oriented `sed`

commands to solve common problems. However, learning `sed`

for yourself enables you to write your own one-liners, and those can be tailored to your specific needs.

Scripts for `sed `

can be written as lines in a terminal, or they can be saved to a file and executed with `sed`

itself. I tend to write small scripts all as one command because I find myself rarely re-using `sed`

commands in real life. When I write a `sed `

script, it’s usually very specific to one file. For example, after writing the initial draft of this very article, I used `sed`

to standardize the capitalization of "sed", and that’s a task I’ll probably never have to do again.

You can issue a series of distinct commands to `sed`

separated by a semicolon (`;`

).

```
$ sed ‘3t ; s/line/\U&/’ example.txt
hello
world
This is LINE three.
This is the final line.
```


## Scope changes with braces

You can also limit which results are affected with braces (`{}`

). When you enclose `sed`

commands in braces, they apply only to a specific selection. For example, the word "line" appears in two lines of the sample text. You can force `sed`

to affect only the final line by declaring the required match condition (`$`

to indicate the final line) and placing the `s`

command you want to be performed in braces immediately thereafter:

```
$ sed ‘$ {s/line/\U&/}’ example.txt
hello
world
This is line three.
This is the final LINE.
```


## Learn Sed

You can do a lot more with `sed`

than what’s explained in this article. I haven’t even gotten to branching (`b`

), tests (`t`

), the *hold* space (`H`

), and many other features. Like [ ed](https://opensource.com/article/20/12/gnu-ed),

`sed `

probably isn’t the text editor you’re going to use for document creation or even for every scripted task you need doing, but it is a powerful option you have as a POSIX user. Learning how `sed`

commands are structured and how to write short scripts can make for quick changes to massive amounts of text. Read through the `info`

pages of GNU `sed`

, or the man pages of BSD `sed`

, and find out what `sed`

can do for you.
## 1 Comment