sed流编辑器
“sed是用于过滤和转换文本的流编辑器。”
概述
sed,全称为stream editor,是一个非交互式的编辑器。
sed命令是利用script来处理文本文件。sed可依照script的指令,来处理、编辑文本文件。
sed主要用来自动编辑一个或多个文件;简化对文件的反复操作;编写转换程序等。
sed基本知识点
sed工作流程

前提:待操作文本是由至上而下的一行或N行组成。
基本工作流程:
- 当用
sed命令对文本进行处理的时候,sed先读取对象的文本文件的第一行到模式空间中。 - 当有内容进入
模式空间时,sed的编辑命令对模式空间中的内容进行编辑操作(修改,替换,删除,追加,显示等等) 模式空间中的内容编辑处理完成之后,sed把此内容通过标准输出(默认为显示器)打印出来,并删除模式空间中的内容。- 第一行处理结束。从新读取第二行的内容进行处理,直到最后一行。
- 当用
注意:持有空间可以和模式空间的内容进行互相追加、覆盖等操作。
sed命令执行位置
几乎所有的sed命令都可以添加[address[,address]]来确定命令执行的位置,完整指令如下:
1 | # !表示匹配成功后是否执行命令 |

命令执行位置可以使用相对位置:
1 | # 匹配a并输出a和其后连续两行,+2表示其后连续两行 |

sed命令打包
sed命令可以用大括号进行分组作为嵌套命令,表示外层命令执行完成后,再执行内层命令:
1 | # 对3行到第4行,执行命令/I am/d |

持有空间
持有空间(Hold Space),可以存放模式空间中的内容,也可以取出内容追加或覆盖到模式空间中。
常用命令参数如下:
| 参数 | 说明 |
|---|---|
g |
将hold space中的内容拷贝到pattern space中,原来pattern space里的内容清除 |
G |
将hold space中的内容append到pattern space后 |
h |
将pattern space中的内容拷贝到hold space中,原来的hold space里的内容被清除 |
H |
将pattern space中的内容append到hold space后 |
x |
交换pattern space和hold space的内容 |
示例如下:
1 |
|

具体过程如下:

1 | # 将文件进行反序 |

其中的 ‘1!G;h;$!d’ 可拆解为三个命令:
- 1!G —— 只有第一行不执行G命令,将hold space中的内容append回到pattern space
- h —— 每一行都执行h命令,将pattern space中的内容拷贝到hold space中
- $!d —— 除了最后一行不执行d命令,其它行都执行d命令,删除当前行
具体过程如下:

sed命令
常用参数介绍
sed命令的语法为:sed [参数]... [执行命令] [输入文件]...
1 | sed -i "1s/Hello/World/" test |

常用参数如下:
| 参数 | 说明 |
|---|---|
-n |
安静模式,只打印受影响的行,默认打印输入数据的全部内容 |
-e script |
用于在脚本中添加多个执行命令一次执行,在命令行中执行多个命令通常不需要加该参数 |
-f filename |
指定执行filename文件中的命令 |
-r |
使用扩展正则表达式,默认为标准正则表达式 |
-i |
将直接修改输入文件内容,而不是打印到标准输出设备 |
sed编辑器的执行命令
sed的执行命令格式如下:
1 | [n1][,n2]command |
1 | # 具体命令如下: |

其中n1,n2表示输入内容的行号,它们之间为,逗号则表示从n1到n2行,如果为~波浪号则表示从n1开始以step为步进的所有行;command为执行动作,下面为一些常用动作指令:
| 命令 | 说明 |
|---|---|
s |
行内替换 |
c |
整行替换 |
a |
插入到指定行的后面 |
i |
插入到指定行的前面 |
p |
打印指定行,通常与-n参数配合使用 |
d |
删除指定行 |
g |
一行上替换所有匹配 |
操作实例
- 打印指定行
1 | sed -n '1,6p' test # 打印1到6行 |

- 行内替换
1 | # 将所有wen替换为hi |

- 行间替换
1 | # 将第五行替换为wonderful |

- 行首插入字符
1 | # 在每行头部插入#+空格 |

- 行尾插入字符
1 | # 在每行行末插入空格+! |

- 行间插入字符
1 | # 在第一行之前插入hello |

- 指定替换内容
将数字n放在脚本头部表示匹配第n行:
1 | # 替换第3行的所有a |

将数字n放在脚本尾部表示匹配每行的第n个字符:
1 | # 替换每一行的第2个s |

- 多个匹配
如果需要一次性匹配多个模式,可使用命令:
1 | echo "a\naa\naaa\naaaa\naaaaa\naaaaaa" | sed "1,3 s/a/A/g; 4,$ s/a/B/g" |

注意: 4,$ s/A/B/g两个命令之间是有空格的。
- 使用匹配的变量
1 | # 每个aaa都用中括号圈起来 |

- 圆括号匹配
1 | # 匹配到aaa+任意字符串则将整个字符串划分为aa:a+任意字符串,\1表示匹配第一个括号的内容,\2同理 |

- 删除行
1 | # 删除匹配aa的行 |

sed的命令还有很多丰富的使用方法,可以参见官方手册