概念
sed全名为Stream Editor 流式编辑器,用我们的程序的方式来编辑文本,功能很强大。sed是grep的继任者。与vim 等这些编辑器不同,sed是一中非交互式的编译器,(用户不用去参与编辑过程)
sed是用我们的预先设定好的编辑指令对输入的文本进行编辑,完成之后把结果输出到屏幕
sed基本上都是使用正则模式匹配。
sed是一个古老的编译器,是在1973年到1974之间出现的,在贝尔(at&t 美国电话电报公司IBM )实验室(晶体管,C,c++,UNIX第一台有界面的系统,)谷歌实验室(最早实验无人驾驶,大数据----发表了三篇论文 Doug Cutting狗哥)开发完成,
sed工作原理:
sed会一次处理我们的一行内容。处理时,把当前处理的行存储在临时缓冲区,成为“模式空间”,接着使用sed命令处理缓冲区里面的内容,处理完成后把缓冲区的内容送往屏幕,接者处理下一行,这样不断重复,直到文件末尾。文件内容没有改变,除非使用重定向存储输出。
缓冲区:缓冲区又称为缓存,它是内存空间的一部分。也就是说,在内存空间中预留了一定的存储空间,这些存储空间用来缓冲输入或输出的数据,这部分预留的空间就叫做缓冲区。缓冲区根据其对应的是输入设备还是输出设备,分为输入缓冲区和输出缓冲区
正则匹配过程:
就是拿个正则表达式所表示的字符串去和原字符串进行匹配,直到匹配到原串中一个完整的子串就表示匹配成功。-----原串内容“this is better desk” 正则表示esk
使用sed
语法格式:
语法: 命令 | sed 选项 (定位符) 指令
sed 选项 (定位符) 指令 文件名 # (定位符) 指令 相对文件的哪一行进行操作
选项
-n 屏蔽默认输出
-r 支持我们的扩展正则
-i写入文件
sed‘定位符 指令’
数据定位
行号定位 通果行号进行定位
[root@localhost ~]# sed -n "2p" /etc/hosts // 屏蔽默认输出,打印第二行
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
[root@localhost ~]#
[root@localhost ~]# sed "2p" /etc/hosts //没有屏蔽默认输出,打印第二行
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
打印1-3行
[root@localhost ~]# sed -n "1,3p" /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
[root@localhost ~]#
打印奇数行 1~2从第一行行开始每次行号自加2
[root@localhost ~]# sed -n "1~2p" /etc/passwd
打印偶数行
[root@localhost ~]# sed -n "2~2p" /etc/passwd
打印从第2行开始后面连续的三行 2,+定位符
[root@localhost ~]# sed -n "2,+3p" /etc/passwd
正则定位
sed可以使我们的正则定位到自己需要的编辑内容 (///)
[root@localhost ~]# sed -n "/^root/p" /etc/passwd 过滤以root开头的行 /字符/ //的作用怕与p混淆
[root@localhost ~]# sed -rn "/[0-9]{3}/p" /etc/passwd 过滤三位数
sed修改配置:
sed编辑指令
常用指令
p(print):打印
d(delete): 删除
c(replace): 替换
s(substitution):替换关键字
=: 打印行号
过滤数据(print指令)
过滤网卡的ip信息
[root@localhost ~]# sed -nr "/IPADDR/p" /etc/sysconfig/network-scripts/ifcfg-ens33 IPADDR=192.168.128.51
使用管道,过滤内存信息(如果获取内存的具体值,/proc/meminfo 展示所有的内存信息free)
[root@localhost ~]# free | sed -n "/Mem/p"
Mem: 997952 639448 72704 2928 285800 151652
[root@localhost ~]#
过滤磁盘根分区。
[root@localhost ~]# df -h | sed -n "/\/$/p" \紫色表示转移将后边的/进行转换, 黄色为一个整体//
/dev/mapper/centos-root 17G 4.9G 13G 29% /
打印不连续的多行
[root@localhost ~]# sed -n "1p;2p;4p" /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
[root@localhost ~]#
不打印第2行,其他都打印(出现!使用单引号包起来)
[root@localhost ~]# sed -n '2!p' /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
[root@localhost ~]#
删除数据(delete指令 不加-i选项原文不会受影响)
删除etc/hosts的全部内容。(如果·我们没有指定定位符默认匹配全文)
[root@localhost ~]# sed 'd' /etc/hosts
把系统文件重定向到新文件
[root@localhost ~]# cat /etc/fstab > /tmp/fstab
[root@localhost ~]# cat /tmp/fstab
[root@localhost tmp]# sed '1,3d' fstab #删除一到三行
[root@localhost tmp]# sed '/dev/!d' fstab # 删除不包含dev的
[root@localhost tmp]# sed '/^#/d' fstab #删除以#号开头的行
[root@localhost tmp]# sed '/^$/'d fstab # 删除空行
[root@localhost tmp]# sed -i'1,3d' fstab # 用久删除1到3行
替换行(replace指令 -c)
[root@localhost tmp]# sed 'c 123' fstab 将fstab全部替换为123
123
123
123
123
123
123
123
123
123
123
[root@localhost tmp]# sed '/IPADDR/c IPADDR=1.1.1.1' /etc/sysconfig/network-
scripts/ifcfg-ens33 将网卡的信息ip地址进行替换。
[root@localhost tmp]# sed '/127/c 127.0.0.1 localhost' /etc/hosts //将文件host第一行进行替换,找不同的地方都可以进行替换。·
[root@localhost tmp]# cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
[root@localhost tmp]# sed '/127/c 127.0.0.1 localhost' /etc/hosts
127.0.0.1 localhost
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
[root@localhost tmp]# cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
[root@localhost tmp]# sed '/0/c 127.0.0.1 localhost' /etc/hosts
127.0.0.1 localhost
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
将shell文件第四行替换成xxxx
[root@localhost tmp]# sed '4c xxxx' /etc/shells
/bin/sh
/bin/bash
/sbin/nologin
xxxx
替换关键字 ( 区域(表示第几行)/// 区域(哪一个旧的内容))
格式:s /旧的/新的/
新建文件 s表示每一行的第一个。
[root@localhost day04]# vim test.txt
2046 2048 2046 2046
1001 2046 2999 1888
2046 2046 2046 2046
//每行的一个2046替换成了xxxx (最后一个/没有写东西和/1等效)
[root@localhost day04]# sed 's/2046/xxxx/1' test.txt
[root@localhost day04]# sed 's/2046/xxxx/' test.txt
xxxx 2048 2046 2046
1001 xxxx 2999 1888
xxxx 2046 2046 2046
//将每行的每一个2046替换长xxxx
[root@localhost day04]# sed 's/2046/xxxx/g' test.txt
xxxx 2048 xxxx xxxx
1001 xxxx 2999 1888
xxxx xxxx xxxx xxxx
//将每一行的第二个2046替换xxxx
[root@localhost day04]# sed 's/2046/xxxx/2' test.txt
2046 2048 xxxx 2046
1001 2046 2999 1888
2046 xxxx 2046 2046
//&为代替之前内容,将我们每一行的第一个2046替换成(2046)----&可以在新的位置引用前面旧的内容
[root@localhost day04]# sed 's/2046/(&)/' test.txt
(2046) 2048 2046 2046
1001 (2046) 2999 1888
(2046) 2046 2046 2046
//将第二行的每一个2046替换成xxxx ---s(默认每一行)数字s(数字对应的这一行)
[root@localhost day04]# sed '2s/2046/xxxx/g' test.txt
2046 2048 2046 2046
1001 xxxx 2999 1888
2046 2046 2046 2046
//替换空等同于删除。
[root@localhost day04]# sed 's/2046//1' test.txt
2048 2046 2046
1001 2999 1888
2046 2046 2046
//替换
[root@localhost day04]# sed '2s/2046/xxxx/p' test.txt
2046 2048 2046 2046
1001 xxxx 2999 1888
1001 xxxx 2999 1888
2046 2046 2046 2046
//单独打印,将第二行的每一个2046替换成xxxx -n 屏蔽默认输出
[root@localhost day04]# sed -n '2s/2046/xxxx/p' test.txt
1001 xxxx 2999 1888
将替换符(/)改为其他字符也可以达到一样的操作
[root@localhost day04]# sed 's#2046#xxxx#g' test.txt
xxxx 2048 xxxx xxxx
1001 xxxx 2999 1888
xxxx xxxx xxxx xxxx
[root@localhost day04]# sed 's,2046,xxxx,g' test.txt
xxxx 2048 xxxx xxxx
1001 xxxx 2999 1888
xxxx xxxx xxxx xxxx
[root@localhost day04]# sed 's.2046.xxxx.g' test.txt
xxxx 2048 xxxx xxxx
1001 xxxx 2999 1888
xxxx xxxx xxxx xxxx
//数字也可以当作替换符 (在s的后边/=\表面数字是替换符才能正常替换)
[root@localhost day04]# sed 's120461xxxx1g' test.txt
xxxx 2048 xxxx xxxx
1001 xxxx 2999 1888
xxxx xxxx xxxx xxxx
[root@localhost day04]# sed 's2\20462xxxx2g' test.txt
xxxx 2048 xxxx xxxx
1001 xxxx 2999 1888
xxxx xxxx xxxx xxxx
[root@localhost day04]# sed 's320463xxxx3g' test.txt
xxxx 2048 xxxx xxxx
1001 xxxx 2999 1888
xxxx xxxx xxxx xxxx
正则符号()具有保留功能
-r支持扩展正则 \3和第三个()对应,\2和第2个()对应 \1和第一个()对应
()具有保留功能 \数字和前面()的顺序绑定
[root@localhost ~]# echo "hello the world" | sed -r 's/^(.)(.*)(.)$/\2\1\3/'
ello the worlhd
打印行号(=)
[root@localhost ~]# sed -n '1=' /etc/passwd //打印第一行的行号
1
[root@localhost ~]# sed -n '2=' /etc/passwd
2
[root@localhost ~]# sed -n '/root/=' /etc/passwd //打印包含root行的行号
1
10
[root@localhost ~]# sed -n '/bash$/=' /etc/passwd //打印包含bash结尾行的行号
1
44
46
47
[root@localhost ~]# sed -n '$=' /etc/passwd 查看passwd文件有多少行。
47
[root@localhost ~]# wc -l /etc/passwd
47 /etc/passwd