一、基础
1.1、语法格式
sed [选项] [sed指令] [输入文件]
-e 支持对单个文件实现不同的操作;
sed -e '/^#/d' -e '/^$/d' file # 删除注释行 和 空白行
-i 直接修改文件内容{默认不会对文件直接操作};
1.2、工作原理
二、功能
2.1、增
- 测试文件
[root@localhost tmp]# cat file
hello world
heello linux
how are you
i am fine
# 匹配world字符的行,行首添加字符Li
sed '/world/s/^/Li /' file
# 匹配you字符的行,在行尾添加字符 Li
sed '/you/s/$/ Li/' file
或
sed '/you/s/\(.*\)/\1 Li/g ' file
用正则表达式,\(\)表示分组,.*表示任意字符,\1引用第一个分组,因为匹配的是任意字符,所有整行都匹配了,在添加的时候就添加到行尾了。
# 匹配linux字符的行,在linux字符的前面添加字符jie
sed 's/linux/jie &/' file
# 匹配linux字符的行,在linux字符后面添加字符jie
sed 's/linux/& jie/' file
# 在匹配are字符的行前面添加一行nihao
sed '/are/i nihao' file
或
sed '/are/i\nihao' file
错误示范:
[root@localhost tmp]# sed '/are/i/nihao' file
hello world
heello linux
/nihao # 注意,这不是在匹配are字符的行前面添加nihao
how are you
i am fine
thanks, andyou
# 在匹配are字符的行后面,添加你好这行
sed '/are/a nihao' file
# 匹配行的后面添加多行
sed '/are/a\nihao\n wo hen hao' file # 添加多行要用\n来转义
# 在每行的开头添加start
sed 's/^/Start /' file
# 在每行的行尾添加End字符
sed 's/$/ End/' file
# 在指定行首添加#号
sed '1,3s/^/# /' file
2.2、删
- 测试文件
[root@localhost tmp]# cat file
sed command
#hello world tail and tail
#hello linux tail and tail
#how are you End
i am fine End
thanks,and you End
sed command end
- 删除匹配行
# 删除以#号开头的行
sed '/^#/d' file
# 删除以非#号开头的行,即显示以#号开头的行
sed '/^#/!d' file
# 删除文件的第一行,即首行
sed '1d' file
# 删除文件的最后一行,即尾行
sed '$d' file
# 删除文件指定范围的行
sed '2,4d' file
# 删除匹配thanks字符的行
sed '/thanks/d' file
# 删除文件中含有you这个单词的行
sed '/\<you\>/d' file
2.3、改
- 测试文件1
[root@localhost tmp]# cat file
#hello world tail and tail
#hello world tail and tail
#how are you End
i am fine End
i am file End
thanks,and you End
- 替换字符串
# 匹配tail的行,把tail换成end,默认修改行中第一次出现的tail
sed '/tail/s/tail/end/' file
# 后面跟g是修改全文,只要出现tail的就替换成end
sed '/tail/s/tail/end/g' file
# 数字后接g,表示匹配的行中,第几次出现,就替换,2g表示替换行中第二次及之后出现的字符串
sed '/tail/s/tail/end/2g' file
- 测试文件2
[root@jie1 ~]# cat test
anonymous_enable=YES
write_enable=YES
local_umask=022
xferlog_enable=YES
connect_from_port_20=YES
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
DEVICE="eth0"
BOOTPROTO="static"
HWADDR="00:0C:29:90:79:78"
ONBOOT="yes"
IPADDR=172.16.22.1
NETMASK=255.255.0.0
- 操作示范
# 匹配DEVICE的行,替换成Ethernet
sed '/DEVICE/c\Ethernet' file
# 把static替换成dhcp(非行中第一次出现要加g)
sed 's/static/dhcp/' file
# 把22.1替换成10.12,由于.号有特殊意义,所以需要转义
sed '/IPADDR/s/22\.1/10\.12/' file
# 匹配connect的行,把YES替换成NO
sed '/connect/s/YES/NO/' file
# 把所有匹配到bin的行中,第二次及第二次之后出现的bin替换成tom;
sed '/bin/s/bin/tom/2g' file
#把所有匹配到bin的行中第二次出现的daemon替换成jerry,并打印与匹配行同样的行
sed 's/daemon/jerry/2p' file
#把所有匹配到adm的行中仅仅只是第二次出现的adm替换成boss
sed 's/adm/boss/2' file
#匹配root的行,把bash替换成nologin,且把0替换成1
sed '/root/{s/bash/nologin/;s/0/1/g}' file
#把root用括号括起来,&表示引用前面匹配的字符
sed 's/root/(&)/g' file
#匹配BOOTPROTO替换成#BOOTPROTO,在配置文件中一般用于注释某行
sed 's/BOOTPROTO/#BOOTPROTO/' file
或
sed 's/BOOTPROTO/#&/' file
#匹配YES的行,并注释
sed '/YES/s/^/#/' file
#匹配ONBOOT的行,把#替换成空,即去掉#号,也一般用作去掉#注释
sed '/ONBOOT/s/#//' file
2.4、查
- 单行
sed -n '1p' data
p:打印模式空间的内容;
-n:取消sed默认输出;
- 多行
# 默认匹配所有行
sed -n 'p' data
# 匹配连续的行(第1~3行)
sed -n '1,3p' data
# 匹配不连续的行(第1~5行和第9行)
sed -n '1,5p;9p' data
逗号,表示接连续的行;
分号,表示接特定的行;
- 过滤多个字符
老版本需要 -r 支持扩展正则表达式,centos7 不需要
或
sed -n '/hello\|world/p' data
与
sed -n '/hellp/{/world/p}' data
2.5、通用
- 文本定位
代码 | 功能 | 示例 |
---|---|---|
x | x为行号 | 打印文本中第二行:sed -n '2p' data sed 默认会打印文件中所有的行,-n 表示只打印匹配的行; |
x,y | 表示行号从x到y | 打印文本中第一行到第三行:sed -n '1,3p' data 在上一显示中,显示行号: sed -n '1,3{=;p}' (当用到sed 不同的编辑命令是,用{},且不同编辑命令之间用分号) |
/pattern/ | 查询包含模式的行 | 打印文本中匹配字符串 ‘second’ 的行:sed -n '/second/p' data |
/pattern/,/pattern/ | 查询包含两个模式或的行 | 打印匹配字符data或last的行:sed -n '/data/,/last/p' data 或sed -n '/data\|last/p' data |
/pattern/{/pattern/p} | 查询包含两个模式与的行 | 打印匹配字符data和last的行:sed -n '/data/{/last/p}' data |
/pattern/,x | 在给定行号上查询包含模式的行 | 打印文本中从匹配 first 的行 到第四行:sed -n '/first/,4p' data |
x,/pattern/ | 通过行号和模式查询匹配的行 | 打印第二行到匹配到第一次出现last的行:sed -n '2,/last/p' data |
x,y! | 查询不包含指定行号x和y的行 | 打印非1到2行:sed -n '1,2!p' data |
- 编辑命令
代码 | 功能 | 示例 |
---|---|---|
p | 打印匹配行,常与-n选项搭配使用 | |
= | 显示行号 | |
a\ | 在定位行号后附加文本信息 | |
i\ | 在定位行号后插入文本信息 | |
d | 删除定位行 | |
c\ | 用新文本替换定位文本 | |
w filename | 写文本到一个文件,类似重定向 > | |
r filename | 从另一个文件中读文本,类似输入重定向 < | |
s | 使用替换模式替换相应模式 | |
q | 第一个模式匹配完成后退出或立即退出 | 打印前5行:sed '5q' file |
l (小写L) | 显示八进制ACSII代码等价的控制符 | |
{} | 多个编辑命令时,用分号隔开 | |
n | 从另一个文件中读文本下一行,并从下一条命令而不是第一条命令开始对其的处理 | |
N | 在数据流中添加下一行以创建用于处理的多行组 | |
g | 将模式2粘贴到/pattern n/ | |
y | 传送字符,替换单个字符 |
- 正则表达式
代码 | 功能 | 示例 |
---|---|---|
^ | 锚定行首 | 过滤以#开头的行:sed -n '/^#/!p' file |
$ | 锚定行尾 | 过滤以A结尾的行:sed -n '/A$/!p' file |
^$ | 空白行 | 过滤 空白行 :sed -n '/^$/!p' file |
. | 任意单个字符 | |
* | 匹配紧挨在前面的字符任意次(0,1,多次) | 打印匹配r有0个或多个,后接一个t字符的行:```sed -n ‘/r*t/p file’ |
.* | 匹配任意长度的任意字符 | 打印匹配r后接任意字符的行:sed -n '/r.*/p' file |
\? | 匹配紧挨在前面的字符0次或1次 | |
\{m,n\} | 匹配其前面的字符至少m次,至多n次 | 打印 o 字母重复出现1次到3次之间的行:sed -n '/o\{1,3\}/p file' |
\{m,\} | 匹配其前面的字符至少m次 | 打印 o 字母重复一次及以上的行:sed -n '/o\{1,\}/p file' |
\{m\} | 精确匹配前面的字符m次 | 打印 o 字母重复3次的行:sed -n '/o\{3\}/p file' |
\< | 锚定词首,相当于\b | |
\> | 锚定词尾 | |
\<pattern\> | 锚定单独一个单词 | |
分组,用法格式:pattern,引用\1,\2 | ||
[] | 匹配指定范围内的任意单个字符 | |
[^] | 匹配指定范围外的任意单个字符 | |
[:digit:] | 所有数字,相当于[0-9] | |
[:lower:] | 所有小写字母,相当于[a-z] | |
[:upper:] | 所有大写字母,相当于[A-Z] | |
[:alpha:] | 所有的字母,相当于[a-zA-Z]或[a-Z] | |
[:alnum:] | 所有字母和数字,相当于[0-9a-zA-Z] | |
[:space:] | 空白字符 | |
[:punct:] | 所有标点符号 |
2.6、高级用法
-
引用变量
第一种:当sed命令里面没有默认的变量时可以把单引号改成双引号;
第二种:当sed命令里面有默认的变量时,那自己定义的变量需要加单引号,且sed里面的语句必须用单引号; -
写入文本{w}
[root@jie1 ~]# cat file
Ethernet
#BOOTPROTO="dhcp"
HWADDR="00:0C:29:90:79:78"
ONBOOT="yes"
IPADDR=172.16.10.12
NETMASK=255.255.0.0
[root@jie1 ~]# sed -i 's/IPADDR/ip/w ip.txt' file
step1:替换源文件;
step2:将替换的内容,重定向到ip.txt中(覆盖保存);
[root@jie1 ~]# cat ip.txt #查看新文件的内容
ip=172.16.10.12
[root@jie1 ~]#
- 读取文本{r}
[root@jie1 ~]# cat file1 #文件内容
hello world
i am li
how are you
li
[root@jie1 ~]# cat file2 #将用sed操作的文件的内容
Ethernet
#BOOTPROTO="dhcp"
HWADDR="00:0C:29:90:79:78"
ONBOOT="yes"
IPADDR=172.16.10.12
NETMASK=255.255.0.0
#在匹配Ethernet的行,在下一行读进来另一个文件的内容
[root@jie1 ~]# sed -i '/Ethernet/r myfile1' file2
[root@jie1 ~]# cat file2
Ethernet
hello world
i am li
how are you
li
#BOOTPROTO="dhcp"
HWADDR="00:0C:29:90:79:78"
ONBOOT="yes"
IPADDR=172.16.10.12
NETMASK=255.255.0.0