`sed`流编辑器配合正则表达式,从文件或管道中每次读取一行数据,都会把当前处理一行数据存储在临时内存缓冲区中,称为sed模式空间(Pattern Space)
## 常用选项
| 选项 | 描述 |
| ------------ | ------------------------------------------------------------ |
| -n | 关闭sed默认输出功能,只输出script处理过的信息 |
| -e | 指定多个script指令,多点匹配 |
| -f | 从指定文件读取script指令 |
| -r | 识别扩展正则表达式 |
| -i<备份后缀> | sed默认处理数据不影响文件原内容,-i 参数编辑文件并备份原文件,禁止配合-n参数 |
## sed 处理指令
| 指令 | 描述 |
| ------ | ------------------------------------------ |
| p | 输出script处理的数据行 |
| Ip | I 参数忽略过滤信息大小写 |
| d | 删除模式匹配的行 |
| a\ | 模式匹配的行后面追加内容信息,并处理下一行 |
| i\ | 模式匹配的行前面追加内容信息,并处理下一行 |
| c\ | 替换指定整行信息 |
| w file | 保存模式匹配的行至指定文件 |
| r file | 读取指定文件的文本至模式空间中匹配到的行后 |
| = | 显示匹配到信息所在行号 |
| ! | 取反 |
| ; | 同参数 -e |
## 搜索替换格式:
**s/regexp/replacement/修饰符**,支持使用其它分隔符,可以是其它形式:s@@@,s###
| 修饰符 | 描述 |
| -------- | ---------------------------------------------------- |
| 无修饰符 | 表示只替换每一行第一个匹配到的文本 |
| g | 表示行内全面替换,不输出文本,Ng表示替换匹配到的前N行 |
| p | 表示打印替换后文本 |
| w | 表示被替换信息写入一个文件 |
| I / i | 替换忽略字母大小写 |
## sed 处理地址
| 处理地址 | 描述 |
| ------------------------- | ------------------------------------------------------------ |
| 无地址 | 对文件全文处理 |
| n | 指定第几行处理 |
| $ | 处理文件最后一行 |
| /regexp/ | 正则匹配,匹配到的文本处理。加上 -r 参数,支持扩展正则表达式 |
| n,m | 范围匹配,指定从n行到m行文本处理 |
| n,+m | 范围匹配,指定从n行到n+m行文本处理 |
| /regexp1/ **,** /regexp2/ | 范围匹配,指定从regexp1匹配到行到regexp2匹配到行处理 |
| n,/regexp/ | 范围匹配,指定从n行到regexp匹配到行处理 |
| n~m | 步长匹配,1~2 表示从第一行过滤奇数行,2~2表示过滤偶数行 |
## sed用法范例
### 1.打印输出 sed -n
sed命令默认会把读取到文本打印到屏幕,sed -n 表示只打印输出处理的数据文本行。
输出文件全文内容,以下俩个用法等价
```
[root@centos7 ~]#sed "" /etc/passwd
[root@centos7 ~]#sed -n "p" /etc/passwd
```
### 2.地址匹配
输出指定具体第几行,比如输出/etc/passwd文件的第10行
```
sed -n "10p" /etc/passwd
```
打印文件的最后一行文本
```
sed -n "$p" /etc/passwd
```
### 3.范围匹配
范围匹配:是指从一个范围开始位置匹配到结束位置。
打印第一到第五行信息
```
sed -n '1,5p' /etc/passwd
```
打印第一行到最后一行信息
```
sed -n '1,$p' /etc/passwd
```
打印第五行后面三行信息
```
sed -n '5,+3p' /etc/passwd
sed -n '5,8p' /etc/passwd
```
### 4.步进匹配
打印奇数行
```
seq 10|sed -n '1~2p'
seq 10|sed -n 'p;n'
seq 10|sed 'n;d'
```
打印偶数行
```
seq 10|sed -n '2~2p'
seq 10|sed -n 'n;p'
seq 10|sed '1!n;d'
```
### 5.删除操作 d
删除空白行
```
sed '/^$/d' /etc/ssh/sshd_config
```
删除文件指定行
```
sed '2d' /etc/passwd
```
删除文件第二行到第六行
```
sed '/2,6/d' /etc/passwd
```
删除以字母d开始的行到以m开头的行,注意点:如果只匹配到字母d开头,文件末尾也没有匹配到字母m开头,则删除字母d到文件末尾
```
sed '/^d/,/^m/d' /etc/passwd
```
### 6.追加操作 a
在/etc/passwd文件的第五行后追加一行信息“this is test append”
```
sed "5a\this is test append" /etc/passwd
```
在/etc/passwd文件中以root开头的行追加一行信息“this is test append”
```
sed -n "/root/a\this is test append" /etc/passwd
```
```
seq 15 | sed '5,10a hello'
```
```
[root@centos7 ~]#sed -i '7a alias test=ls' .bashrc
[root@centos7 ~]#sed -n '8p' .bashrc
alias test=ls
```
### 7.插入操作 i
在/etc/passwd文件的第三行前插入信息“this is test insert”
```
sed '3i\this is test insert' /etc/passwd
```
在/etc/passwd文件中以root开头的行前插入信息 “this is test insert”
```
sed '/root/i\this is test insert' /etc/passwd
```
```
seq 10 | sed -e '5i\123' -e '5a\456'
```
### 8.替换操作 c
指令c,表示把匹配到一整行信息替换
把第四行信息替换为“this is test replace”
```
seq 10 | sed "4c\this is test replace"
```
正则匹配到的整行替换
```
seq 10 | sed -r "/[235]/c\this si test replace"
```
### 9.写入文件 w
把/etc/passwd文件中以nologin结尾的行写入到/data/nologin.log文件
```
sed -n '/nologin$/w /data/nologin.log' /etc/passwd
```
```
[root@centos7 ~]#sed -n '/^b/w /data/sed.log' /etc/passwd
[root@centos7 ~]#cat /data/sed.log
bin:x:1:1:bin:/bin:/sbin/nologin
boss:x:1002:1003::/home/boss:/bin/bash
```
```
[root@centos7 ~]#sed -n '1w /data/sed.log' /etc/passwd
[root@centos7 ~]#cat /data/sed.log
root:x:0:0:root:/root:/bin/bash
```
```
[root@centos7 ~]#sed -n '1,5w /data/sed.log' /etc/passwd
[root@centos7 ~]#cat /data/sed.log
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
```
注意:指令w 是覆盖原文件内容,写入新内容
### 10.读入文件 r
把/etc/issue文件内容读入到/etc/passwd文件以root开头的行
```
sed '/^root/r /etc/issue' /etc/passwd
```
把文件内容读写奇数行
```
sed '1~2r /etc/issue' /etc/passwd
```
```
[root@centos7 ~]#sed '/^b/,/^s/r /etc/issue' /etc/passwd
```
### 11.搜索取反
打印/etc/passwd文件中不是以nologin结尾的行
**注意:使用单引号,双引号会把!p认为执行历史命令,建议使用单引号**
```sh
[root@centos7 ~]#sed -n '/nologin$/!p' /etc/passwd
[root@centos7 ~]#sed -n '/root/!p' /etc/passwd
```
把/etc/fstab文件非注释行添加注释,包括空行
```shell
方法一: sed -r '/^#/!s/(.*)/#\1/p' /etc/fstab
方法二: sed -r '/^#/!s/^/#/p' /etc/fstab
```
### 12.显示匹配到的信息所在的行号
```sh
[root@centos7 ~]#sed '/root/=' /etc/passwd
```
### 13.真实修改文件 -i
```
[root@centos7 /data]#sed -n '/root/p' passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
[root@centos7 /data]#sed -i.bak '/root/d' passwd
[root@centos7 /data]#sed -n '/root/p' passwd
[root@centos7 /data]#
[root@centos7 /data]#ls
passwd passwd.bak
[root@centos7 /data]#grep root passwd.bak
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
```
### 14.多点匹配
sed -e 执行多个script进行匹配文件内容,或者关系
打印/etc/passwd文件的第五行和第七行内容
```scss
sed -n '5p;7p' /etc/passwd
sed -n -e '5p' -e '7p' /etc/passwd
```
打印root开头行或者以nologin结尾的行
```scss
sed -n "/^root/p;/nologin$/p" /etc/passwd
sed -n -e "/^root/p" -e '/nologin$/p' /etc/passwd
```
### 15.搜索替换 s
把/etc/passwd文件中的nologin替换为“this is test sub”
```scss
sed 's#nologin$#this is test sub#g' /etc/passwd
```
替换指令 g:表示把文件中匹配到所有字符串进行替换为目标信息
替换指令 p:配合参数 -n ,只打印被替换信息
```scss
sed -n 's#nologin$#this is test sub#gp' /etc/passwd
```
替换指令 w:被替换信息保存到指定文件
```scss
sed -n 's#nologin$#this is test sub#gw /data/sub.log' /etc/passwd
```
过滤替换
```scss
sed '/regexp/s/替换信息/替换目标/g' 文件
```
### 16.忽略大小写 I
```sh
[root@centos7 ~]#sed -n '/ROOT/Ip' /etc/passwd
```
### 17.引用变量
ed表达式可以使用单引号来引用,但是如果表达式内部包含变量字符串,就需要使用双引号。
```scss
[root@centos7 ~ ]# test=hello
[root@centos7 ~ ]# echo hello WORLD | sed "s/$test/HELLO/"
HELLO WORLD
```
使用单引号引用变量时,需要变量名以三个单引号引起来,echo也适用。
```scss
[root@centos7 ~ ]# test=hello
[root@centos7 ~ ]# echo hello WORLD | sed 's/'''$test'''/HELLO/'
HELLO WORLD
```