前言
我们将/etc/passwd文件拷贝到/data下做实验,以免影响系统
一、特点及格式
sed stream editor 流编辑器,sed把处理的内容(文件),当做是水,源源不断的进行处理,知道文件末尾
sed编辑器可以根据命令来处理数据流中的数据,这些命令从命令行中输入或者存储在一个命令文本文件中,可以理解为脚本
sed常用选项
选项 |
功能 |
-r |
使用了扩展正则需要 |
-e或--expression= |
表示用指定命令来处理输入的文本文件,只有一个操作命令时可以省略,一般在执行多个操作命令使用 |
-f或--file= |
表示用指定的脚本文件来处理输入的文本文件 |
-h或者--help |
显示帮助 |
-n、--quiet或silent |
禁止sed编辑器输出,但可以与p命令一起使用完成输出 |
-i |
直接修改目标文本文件 |
sed命令的核心功能:增删改查
功能 |
含义 |
s |
替换substitute sub |
p |
显示print |
n |
把当前操作移动到下一行操作 |
d |
删除delete |
ai |
增加a/i |
c |
整行替换 |
y | 对应字符转换,转换前后的字符长度必须相同 |
l(小写L) |
打印数据流中的文本和不可打印的ASCII字符(比如结束符$、制表符\t) |
sed的工作流程主要包括读取、执行和显示三个过程:
读取: sed从输入流(文件、管道、标准输入)中读取一行内容并存储到临时的缓冲区中(又称模式空间, pattern space)。
执行:默认情况下,所有的sed命令都在模式空间中顺序地执行,除非指定了行的地址,否则sed命令将会在所有的行上依次执行。
显示:发送修改后的内容到输出流。在发送数据后,模式空间将会被清空。
在所有的文件内容都被处理完成之前,上述过程将重复执行,直至所有内容被处理完。
注意:
默认情况下所有的sed命令都是在模式空间内执行的,因此输入的文件并不会发生任何变化,除非是用重定向存储输出
sed是逐行读取执行显示的,如果文件很大效率会很低,影响IO性能,可以使用“cat 文件 | sed split拆分若干小文件再处理”
命令格式: sed 参数 '操作' 文件1 文件2 sed -e 'n{ 操作1 操作2 ... }' 文件1 文件2 ... 同时处理多个操作需要分行处理,并且带上行号n,否则会全部显示
二、sed核心应用
2.1 sed-查找打印p
查找
查找格式 |
含义 |
'2p' |
指定行号进行查找 |
'1,5p' |
指定行号范围进行查找 |
'/root/p' |
类似于grep过滤,//里面可以写正则 |
'/10:00/,/11:00/p' |
表示范围的过滤,多用于按照时间范围找日志 |
1,/root/p |
混合(从第一行到匹配到root的行) |
#打印内容 [root@localhost data]# sed -e 'p' users.txt 1,zhangsan 1,zhangsan 2,lisi 2,lisi 3,wangwu 3,wangwu 4,zhaoliu 4,zhaoliu 5,qianqi 5,qianqi 6,zhuba 6,zhuba [root@localhost data]# sed 'p' users.txt 1,zhangsan 1,zhangsan 2,lisi 2,lisi 3,wangwu 3,wangwu 4,zhaoliu 4,zhaoliu 5,qianqi 5,qianqi 6,zhuba 6,zhuba #查找第二行内容 [root@localhost data]# sed -n '2p' passwd bin:x:1:1:bin:/bin:/sbin/nologin #查找第1到3行内容 [root@localhost data]# sed -n '1,3p' 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 data]# sed -n '1,+3p' 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 adm:x:3:4:adm:/var/adm:/sbin/nologin #查找第38行到最后一行的内容 [root@localhost data]# sed -n '38,$p' passwd postfix:x:89:89::/var/spool/postfix:/sbin/nologin sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin tcpdump:x:72:72::/:/sbin/nologin zhangsan:x:1000:1000:zhangsan:/home/zhangsan:/bin/bash apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin [root@localhost data]# #显示1-5行 [root@localhost data]# sed -e '5q' 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 adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin #打印行号,不打印内容 [root@localhost data]# sed -n '=' users.txt 1 2 3 4 5 6 #显示非打印字符 [root@localhost data]# sed -n 'l' users.txt 1,zhangsan$ 2,lisi$ 3,wangwu$ 4,zhaoliu$ 5,qianqi$ 6,zhuba$ #同时处理多条操作 [root@localhost data]# sed -n -e '=' -e 'p' users.txt 1 1,zhangsan 2 2,lisi 3 3,wangwu 4 4,zhaoliu 5 5,qianqi 6 6,zhuba [root@localhost data]# sed -n -e '=;p' users.txt 1 1,zhangsan 2 2,lisi 3 3,wangwu 4 4,zhaoliu 5 5,qianqi 6 6,zhuba [root@localhost data]# sed -n ' > = > p > ' users.txt 1 1,zhangsan 2 2,lisi 3 3,wangwu 4 4,zhaoliu 5 5,qianqi 6 6,zhuba #显示奇偶行 [root@localhost data]# sed -n 'p;n' users.txt 1,zhangsan 3,wangwu 5,qianqi [root@localhost data]# sed -n 'n;p' users.txt 2,lisi 4,zhaoliu 6,zhuba
每行出现了两次,一次是p命令打印的,一次是不加-n,sed命令的显示过程
首先sed命令按行读入,然后打印,接着跳到下一行,此时没有操作了,第一次sed操作完成;
开始读入三行
......
过滤
#查找含有root的行 [root@localhost data]# sed -n '/root/p' passwd root:x:0:0:root:/root:/bin/bash operator:x:11:0:operator:/root:/sbin/nologin [root@localhost data]# #查找包含bash或者root的行 [root@localhost data]# sed -nr '/bash|root/p' passwd root:x:0:0:root:/root:/bin/bash operator:x:11:0:operator:/root:/sbin/nologin zhangsan:x:1000:1000:zhangsan:/home/zhangsan:/bin/bash #查找数字出现三次的行,使用扩展正则需要加上-r参数 [root@localhost data]# sed -n '/[0-9]{3}/p' passwd [root@localhost data]# sed -nr '/[0-9]{3}/p' passwd games:x:12:100:games:/usr/games:/sbin/nologin systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin polkitd:x:999:997:User for polkitd:/:/sbin/nologin abrt:x:173:173::/etc/abrt:/sbin/nologin libstoragemgmt:x:998:995:daemon account for libstoragemgmt:/var/run/lsm:/sbin/nologin colord:x:997:994:User for colord:/var/lib/colord:/sbin/nologin saslauth:x:996:76:Saslauthd user:/run/saslauthd:/sbin/nologin setroubleshoot:x:995:993::/var/lib/setroubleshoot:/sbin/nologin rtkit:x:172:172:RealtimeKit:/proc:/sbin/nologin pulse:x:171:171:PulseAudio System Daemon:/var/run/pulse:/sbin/nologin qemu:x:107:107:qemu user:/:/sbin/nologin chrony:x:994:990::/var/lib/chrony:/sbin/nologin usbmuxd:x:113:113:usbmuxd user:/:/sbin/nologin geoclue:x:993:988:User for geoclue:/var/lib/geoclue:/sbin/nologin sssd:x:992:987:User for sssd:/:/sbin/nologin nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin gnome-initial-setup:x:991:986::/run/gnome-initial-setup/:/sbin/nologin zhangsan:x:1000:1000:zhangsan:/home/zhangsan:/bin/bash [root@localhost data]#
表示范围过滤的时候,如果结尾的内容匹配不到就会一直显示到最后一行
2.2 sed-删除d
删除格式 |
|
'2d' |
指定行号进行删除 |
'1,5d' |
指定行号范围进行删除 |
'/root/d' |
类似于grep过滤,//里面可以写正则 |
'/10:00/,/11:00/d' |
表示范围的过滤,多用于按照时间删除找日志 |
1,/root/d |
混合(从第一行到匹配到root的行) |
[root@localhost data]# cat users.txt 1,zhangsan 2,lisi 3,wangwu 4,zhaoliu 5,qianqi 6,zhuba #删除2-3行 [root@localhost data]# sed '2,3d' users.txt 1,zhangsan 4,zhaoliu 5,qianqi 6,zhuba [root@localhost data]# #删除匹配到zhangsan的行,整行删除 [root@localhost data]# sed '/zhangsan/d' users.txt 2,lisi 3,wangwu 4,zhaoliu 5,qianqi 6,zhuba [root@localhost data]# #删除第一个包含字符串2的行到第一个包含字符串3的行 [root@localhost data]# sed '/2/,/3/d' users.txt 1,zhangsan 4,zhaoliu 5,qianqi 6,zhuba
这里的删除其实是不显示,原来的文件并没有删除
sed会读取每行的内容,从第一行位置打开删除功能,到第二个位置删完后关闭删除功能,如果匹配不到第二个位置就删到文件末尾
企业案例:删除文件中的空行和包含井号的行
egrep -v '^$|#' /etc/ssh/sshd_config #-v 取反显示 sed -r '/^$|#/d' /etc/ssh/sshd_config #-r 从文件中读取输入行(使用了正则需要加上-r) sed -nr '/^$|#/!p' /etc/ssh/sshd_config #!的妙用,需要空行和井号的行不显示
仅仅删除空行,下面这条命令也可以
cat /etc/ssh/sshd_config |tr -s "\n"