「」至此。關於一種平面顯示器技術，請見「**表面傳導電子發射顯示器**」。

**sed**（意为**流编辑器**，源自英语""的缩写）是一个使用简单紧凑的编程语言来解析和转换文本Unix实用程序。 

sed由贝尔实验室的李·E·麥克馬洪于1973年至1974年开发， 
并且现在大多数操作系统都可以使用。  sed基于交互式编辑器ed（"editor"，1971）和早期qed（"quick editor"，1965-66）的脚本功能。sed是最早支持正则表达式的工具之一，至今仍然用于文本处理，特别是用于替换命令。用于纯文本字符串操作和"流编辑"的常用工具还有AWK和Perl 。

历史
--

sed是为命令行处理数据文件而构建的早期Unix命令之一，首次出现在Version 7 Unix中 。它很自然地演变成为流行的grep命令的后继。 最初的动机与grep（g/re/p）的替换类似，因此称为"g/re/s"。 考虑到这样的话还会出现针对每个命令的专用程序，例如g/re/d，李·E·麥克馬洪编写了一个通用的面向行的流编辑器，该编辑器后来成为了sed。 sed的语法，特别是把`/`用于模式匹配，把`s///`用于替换，起源于sed的前身ed（当时ed很常用） 而且正则表达式语法影响了其他一些语言，特别是ECMAScript和Perl。后来，更强大的语言AWK问世，这些工具相互补充，让通过shell脚本完成强大的文本处理成为可能。sed和AWK常被认为Perl的祖先和灵感来源，并且影响了Perl的语法和语义，尤其影响了匹配和替换运算符。

GNU sed添加了一些新功能，包括文件的就地编辑 。*Super-sed* 是sed的扩展版本，包含与Perl兼容的正则表达式。sed的另一变体*minised* ，最初埃里克·雷蒙把4.1BSD sed通过逆向工程写成，目前由René Rebe维护。在GNU计划基于新的GNU正则表达式库编写了新版本的sed之前，GNU计划一直使用minised。当前minised包含一些BSD sed的扩展，但不像GNU sed那样功能丰富。它的优点是速度快，占用的内存少。它用于嵌入式系统，是Minix提供的sed版本。

工作模式
----

sed是一个面向行的文本处理实用程序：它从输入流或文件中逐行读取文本到一个称为*模式空间* 的内部缓冲区。每读一行开始一个*循环* 。对于模式空间，sed会应用*sed脚本* 指定的一个或多个操作。sed实现了一种编程语言，其中包含大约25个指定文本操作的*命令* 。对于每个输入行，在运行脚本之后，sed通常输出模式空间（由脚本修改的行），然后从下一行再次开始循环。其他脚本结束行为可通过sed选项和脚本命令获得，例如`d`删除模式空间，`q`退出，`N`立即将下一行添加到模式空间，等等。因此，sed脚本对应于循环体，循环体遍历流的行，其中循环本身和循环变量（当前行号）是隐式的并由sed维护。

可以在命令行上指定sed脚本（ `-e`选项），也可以从单独的文件中读取（ `-f`选项）。sed脚本中的命令可以采用行号或正则表达式的作为*地址* 。该地址确定决定命令何时运行。例如，`2d`将仅在第二个输入行上运行`d`（删除）命令（打印除第二个输入行之外的所有行），而`/^ /d`将删除以空格开头的所有行。一些单独的特殊缓冲区，即*保持空间*，可以由几个sed命令使用，用于在循环之间保持和累积文本。sed的命令语言只有两个变量（"保持空间"和"模式空间"）和类似GOTO的分支功能；然而，这种语言是图灵完备的， 用深奥sed脚本甚至写得出推箱子、打砖块、国际象棋和俄罗斯方块等游戏。 

为输入流的每一行执行一次主循环，在输入的每一行上计算sed脚本。sed脚本的每一行都是模式-动作对，指示着要匹配的模式和要执行的操作，可以将其重新组合为条件语句。因为主循环、工作变量（模式空间和保持空间）、输入和输出流以及默认操作（复制行到模式空间、打印模式空间）是隐式的，所以可以编写简洁的单行程序。例如，以下sed程序：

```
10q
```

将打印输入的前10行，然后停止。

用法
--

### 替换命令

下面的示例显示了sed用于替换的典型（也是最常见的）用法。这种用法确实是sed的最初动机：

```
sed 's/regexp/replacement/g' inputFileName > outputFileName

```

在某些版本的sed中，表达式的前面必须加上`-e`，以表示后面跟着一个表达式。`s`表示替换，而`g`表示全局，这意味着行中的所有匹配项都将被替换。要搜索的正则表达式（即pattern）放在第一个分隔符号（此处为斜杠）之后，而要替换成的字符串跟在第二个分隔符号后面。斜杠（`/`）是传统的符号，起源于ed中的"搜索"字符，但其实在pattern和替换文本中都未出现的任何其他符号都可以用作分隔符号，使其可读性更强；这有助于避免"倾斜牙签综合征"。

替换命令源自ed中的搜索-替换，实现了简单的解析和模板化 。`regexp`提供模式匹配和通过子表达式保存文本的功能，而`replacement`可以是纯文本，也可以是包含"完全匹配"`&`，或第*n* 个子表达式（从`\1`到`\9`）这种特殊转义序列的格式字符串。例如， `sed -r "s/(cat|dog)s?/\1s/g"`用"cat"或"dog"替换所有出现的"cats"或"dogs"，而不复制现有的"s"：在正则表达式中，`(cat|dog)`是第一个（也是唯一）保存的子表达式，格式字符串中的`\1`将其替换到输出里。

### 其他sed命令

除了替换之外，使用大约25个sed命令可以进行其他形式的简单处理。例如，下面使用*d* 命令删除空行或只包含空格的行：

```
sed '/^ \*$/d' inputFileName

```

本例使用了下列正则表达式元字符（sed支持所有正则表达式）：

* 脱字符（ `^` ）匹配行首。
* 美元符号（ `$` ）匹配行尾。
* 星号（ `*` ）匹配前一个字符零次或多次出现。

可以有很复杂的sed结构，让sed用作一种简单但高度专业化的编程语言。例如，可以通过使用标签（冒号后跟字符串）和分支指令`b`来管理控制流程。指令`b`后跟有效的标签名称，将把处理流程移动到该标签后面的块。

### sed用作过滤器

在Unix下，sed通常用作管道中的过滤器：

```
generateData | sed 's/x/y/g'

```

也就是说，诸如"generateData"之类的程序生成数据，然后用sed把*x*替换成*y*。例如：

```
$ echo xyz xyz | sed 's/x/y/g'
yyz yyz

```

### 基于文件的sed脚本

将几个sed命令（每行一个命令）放入脚本文件（例如`subst.sed`）中然后使用`-f`选项从文件中运行命令（例如`s/x/y/g`）通常很有用：

```
sed -f subst.sed inputFileName > outputFileName

```

可以在脚本文件中放置任意数量的命令，使用脚本文件也可以避免shell转义或替换的问题。

这样的脚本文件可以直接从命令行执行，方法是在其前面加上一个包含sed命令的"shebang行"，并为该文件分配可执行权限。例如，可以使用以下内容创建文件`subst.sed`：

```
#!/bin/sed -f
s/x/y/g

```

然后，当前用户可以使用`chmod`命令使文件可执行：

```
chmod u+x subst.sed

```
然后可以直接从命令行执行该文件：

```
subst.sed inputFileName > outputFileName

```

### 就地编辑

GNU sed中引入的`-i`选项允许就地编辑文件（实际上，在后台创建了一个临时输出文件，然后将原始文件替换为临时文件）。例如：

```
sed -i 's/abc/def/' fileName

```

示例
--

### Hello, world! 例子

```
# convert input text stream to "Hello, world!"
s/.*/Hello, world!/
q
```

这个"Hello, world!"脚本位于文件（如script.txt）中，并使用`sed -f script.txt inputFileName`调用，其中"inputFileName"是输入文本文件。脚本将"inputFileName"第1行更改为"Hello, world!"然后退出，在sed退出之前打印结果。第1行后的任何输入行都不会被读取，也不会被打印。唯一的输出是"Hello, world!"。

这个例子强调了sed的许多关键特性：

* sed是独一无二的。没有其他"Hello, world!"例子与之相似。
* 典型的sed程序相当简短。
* sed脚本可以有注释（以`#`符号开头的行）。
* `s`（替换）命令是最重要的sed命令。
* sed允许使用`q`（退出）等命令进行简单编程。
* sed使用正则表达式，例如`.*` （任何字符的零个或多个）。

### 其他简单的例子

下面是各种sed脚本；可以把它们作为参数传递给sed，或者放入一个单独的文件并通过`-f`执行或通过使脚本本身可执行来执行。

要把文件中某个单词（例如IRC密码）替换为"REDACTED"，并保存结果：

```
sed -i s/yourpassword/REDACTED/ ./status.freenode.log

```

要删除包含"yourword"一词的所有行（ *地址* 为"/yourword/"）：

```
/yourword/ d

```

要删除所有"yourword"这个词：

```
s/yourword//g

```

要同时从文件中删除两个单词：

```
s/firstword//g
s/secondword//g

```

为了在一行表示前面的示例，比如在命令行输入时，可以通过分号连接两个命令：

```
sed "s/firstword//g; s/secondword//g" inputFileName

```

### 多行处理示例

在下一个示例中，sed（通常仅在一行上工作）会在某一行的后一行以一个空格打头的情况下删除换行符。
请考虑以下文本：

```
This is my dog,
 whose name is Frank.
This is my fish,
whose name is George.
This is my goat,
 whose name is Adam.
```

下面的sed脚本会将上面的文本转换为以下文本。请注意，该脚本仅影响以空格开头的输入行：

```
This is my dog, whose name is Frank.
This is my fish,
whose name is George.
This is my goat, whose name is Adam.
```

使用的脚本是：

```
N
s/\n / /
P
D
```

这段脚本应按如下理解：

* （`N`）将下一行添加到模式空间；
* （`s/\n / /`）查找一个换行符后跟一个空格，替换为一个空格；
* （`P`）打印模式空间的顶行；
* （`D`）从模式空间中删除顶行并再次运行脚本。

这可以通过分号在一行中表示出来:

```
sed 'N; s/\n / /; P; D' inputFileName
```

限制和替代方案
-------

虽然sed具有简单性和局限性，但对于大量用途而言，它的功能已经足够强大。对于更复杂的处理，可以使用更强大的语言，如AWK或Perl或者PowerShell。虽然使用保持缓冲区理论上可以进行任意复杂的转换，但如果转换行的方式比正则表达式提取和模板替换更复杂，则使用一般会使用上面提到的更强大的语言。

相反，对于更简单的操作，grep （打印匹配模式的行），head（打印文件的第一部分），tail（打印文件的最后部分）和tr（翻译或删除字符）等专门的Unix实用程序通常更可取。对于设计用于执行的特定任务，此类专用实用程序通常比较一般的解决方案（如sed）更简单、清晰和快速。

ed/sed命令和语法继续用于派生程序，例如文本编辑器vi和vim。sam/ssam与ed/sed类似，其中sam是Plan 9编辑器，ssam是它的流接口，其功能类似于sed。

参考文献
----

1. ↑ .  [2013-05-21]. （原始内容存档于2018-06-27）.
2. ↑ .  [2013-05-21]. （原始内容存档于2018-06-27）.
3. 1 2  McIlroy, M. D.  (PDF) (技术报告). CSTR. Bell Labs. 1987  [2018-11-10]. 139. （原始内容存档 (PDF)于2019-11-30）.
4. 1 2 3 4 .  [2018-11-10]. （原始内容存档于2017-09-07）. A while later a demand arose for another special-purpose program, gres, for substitution: g/re/s. Lee McMahon undertook to write it, and soon foresaw that there would be no end to the family: g/re/d, g/re/a, etc. As his concept developed it became sed…
5. ↑ .  [2018-11-10]. （原始内容存档于2018-02-20）.
6. ↑ .  [2018-11-10]. （原始内容存档于2018-01-16）.
7. ↑ .  [2009-04-20]. （原始内容存档于2006-02-08）.
8. ↑ . GitHub.  [2018-11-10]. （原始内容存档于2018-12-02）.
9. ↑ .  [2018-11-10]. （原始内容存档于2018-12-02）.

扩展阅读
----

* 贝尔实验室的第八版（约1985年）Unix sed（1）手册页（页面存档备份，存于）
* GNU sed（1）手册页
* Dale Dougherty & Arnold Robbins.  2nd. O'Reilly. March 1997  [2018-11-10]. ISBN 1-56592-225-5. （原始内容存档于2018-11-02）.
* Arnold Robbins.  2nd. O'Reilly. June 2002  [2018-11-10]. ISBN 0-596-00352-8. （原始内容存档于2018-11-11）.
* Peter Patsis.. Prentice Hall. December 1998  [2018-11-10]. ISBN 0-13-082675-8. （原始内容存档于2020-04-09）.
* Daniel Goldman.. EHDP Press. February 2013  [2018-11-10]. ISBN 978-1-939824-00-4. （原始内容存档于2018-01-29）.
* Sourceforge.net（页面存档备份，存于） ，sed FAQ（2003年3月）

外部链接
----

|  |  |
| --- | --- |
|  | 維基教科書中的相關電子：**en:sed** |

* `sed` – 命令与工具（Commands & Utilities）参考，单一UNIX®规范第7期，由國際開放標準組織发布

### 教程

* Sed - An Introduction and Tutorial（页面存档备份，存于）, by Bruce Barnett
* SED -- A Non-interactive Text Editor (1974)（页面存档备份，存于）, by Lee E. McMahon
* 31+ Examples For Sed Linux Command In Text Manipulation（页面存档备份，存于）, by Mokhtar Ebrahim
* Sed教學（页面存档备份，存于）

### 示例

* Major sources for sed scripts, files, usage
* Roger Chang's SED and Shell Scripts (2012)（页面存档备份，存于）
* Top 'sed' commands – Usage examples
* Sed command examples in Unix & Linux（页面存档备份，存于）

### 其他链接

* GNU sed主页（包括GNU sed手册）
* sed the Stream Editor（2004）（页面存档备份，存于） （Eric Pement）
* sed-users Yahoo讨论组（页面存档备份，存于）

参见
--

* Unix实用程序列表
* AWK
* tr
* PowerShell



|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 

| * 
* 论
* 编
Unix命令行程序和shell内建命令 |
| --- |
|  |
| 文件系統 | 
* cat
* cd
* chmod
* chown
* chgrp
* cksum
* cmp
* cp
* dd
* du
* df
* file
* fsck
* fuser
* ln
* ls
* mkdir
* mount
* mv
* pax（英语：）
* pwd
* rm
* rmdir
* size
* split
* stat
* tee
* touch
* type（英语：）
* umask（英语：）

 |
|  |
| 程序 | 
* at
* bg
* chroot
* cron
* fg
* kill
* killall（英语：）
* nice
* pgrep
* pkill（英语：）
* ps
* pstree（英语：）
* time
* top

 |
|  |
| 用户环境 | 
* clear
* env
* exit
* history（英语：）
* id
* logname
* mesg（英语：）
* passwd
* su
* sudo
* uptime
* talk（英语：）
* tput（英语：）
* uname
* w
* wall（英语：）
* who
* whoami
* write（英语：）

 |
|  |
| 文本编辑 | 
* awk
* banner（英语：）
* basename
* comm（英语：）
* csplit（英语：）
* cut
* diff
* dirname
* ed
* ex
* fmt（英语：）
* fold（英语：）
* head（英语：）
* iconv
* join（英语：）
* less
* more
* nl（英语：）
* paste（英语：）
* sed
* sort（英语：）
* spell（英语：）
* strings（英语：）
* tail
* tr
* uniq（英语：）
* vi
* wc
* xargs

 |
|  |
| 壳层内建 | 
* alias
* echo
* printf格式字符串
* test（英语：）
* unset
* wait

 |
|  |
| 网络 | 
* dig
* host
* ifconfig
* inetd（英语：）
* netcat
* netstat
* nslookup
* ping
* rdate（英语：）
* rlogin（英语：）
* route
* ssh
* traceroute

 |
|  |
| 查找 | 
* find
* grep
* locate
* whatis（英语：）
* whereis

 |
|  |
| 文档 | 
* apropos（英语：）
* help（英语：）
* man

 |
|  |
| 软件开发 | 
* ar
* ctags
* lex
* make
* nm
* strip
* yacc

 |
|  |
| 杂项 | 
* bc
* cal
* dc
* expr
* lp（英语：）
* lpr
* sleep
* true和false
* yes

 |
|  |
| Unix实用程序列表 |

 |