目录
前言
一、特点及格式
?二、sed核心应用
2.1?sed-查找打印p
2.2?sed-删除d
2.3?sed-增加air
2.4?sed-替换scy
2.5?sed-剪切H-粘贴G
总结
前言
我们将/etc/passwd文件拷贝到/data下做实验,以免影响系统
一、特点及格式
选项 | 功能 | -r | 使用了扩展正则需要 | -e或--expression= | 表示用指定命令来处理输入的文本文件,只有一个操作命令时可以省略,一般在执行多个操作命令使用 | -f或--file= | 表示用指定的脚本文件来处理输入的文本文件 | -h或者--help | 显示帮助 | -n、--quiet或silent | 禁止sed编辑器输出,但可以与p命令一起使用完成输出 | -i | 直接修改目标文本文件 |
功能 | 含义 | 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"
2.3?sed-增加air
命令 | 含义 | a | append追加,向指定的每一行追加内容(行后面)>> | i | insert插入,向指定的每一行插入内容(行前面) | r | 在行后增加文件内容 |
[root@localhost data]# cat users.txt
1,zhangsan
2,lisi
3,wangwu
4,zhaoliu
5,qianqi
6,zhuba
[root@localhost data]# sed '1a zhangsan996' users.txt
1,zhangsan
zhangsan996
2,lisi
3,wangwu
4,zhaoliu
5,qianqi
6,zhuba
[root@localhost data]# sed '1i zhangsan996' users.txt
zhangsan996
1,zhangsan
2,lisi
3,wangwu
4,zhaoliu
5,qianqi
6,zhuba
[root@localhost data]# sed '1r ip.txt' users.txt
1,zhangsan
192.168.109.1
192.168.109.2
192.168.109.3
192.168.109.4
192.168.109.5
2,lisi
3,wangwu
4,zhaoliu
5,qianqi
6,zhuba
??
向config里面追加
UseDNS no
GSSAPIAUTCATION no
PermitRootLogin no
#方法一
[root@localhost data]# touch config
[root@localhost data]# cat >>config<<'EOF'
> UseDNS no
> GSSAPIAUTCATION no
> PermitRootLogin no
> EOF
#方法二
[root@localhost data]# sed -i '$a UseDNS no\nGSSAPIAUTCATION no\nPermitRootLogin no' config
2.4?sed-替换scy
替换标记 | 含义 | 数字 | 表明新字符串将替换第几处匹配的地方 | g | 表明新字符串将会替换所有匹配的地方 | p | 打印与替换命令匹配的行,与-n一起使用 | w文件 | 将替换的结果写到文件中 |
s | 字符串替换 | c | 整行替换 | y | 字符转换,转换前后的字符长度必须相同 |
- 分隔符不唯一,只有三个相同就行;
- 前两个分隔符之间支持正则;
- 不加g则是替换每一行第一个被匹配到的内容,g是全局的意思;
- 替换操作类似vim的末行模式;
#每一行的数字替换为空
[root@localhost data]# sed 's/[0-9]//g' users.txt
,zhangsan
,lisi
,wangwu
,zhaoliu
,qianqi
,zhuba
#root替换为admin
[root@localhost data]# sed -n 's/root/admin/p' passwd
admin:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/admin:/sbin/nologin
[root@localhost data]# sed -n 's/root/admin/2p' passwd
root:x:0:0:admin:/root:/bin/bash
#删除前面的所有0
[root@localhost data]# echo 000000001010|sed 's/^0*//'
1010
#给1-10行加上注释
[root@localhost data]# sed '1,10 s/^/#/' 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
#sync:x:5:0:sync:/sbin:/bin/sync
#shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
#halt:x:7:0:halt:/sbin:/sbin/halt
#mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
#operator:x:11:0:operator:/root:/sbin/nologin
......
#将所有root开头的行注释
[root@localhost data]# sed -n 's/^root/#root/p' passwd
#root:x:0:0:root:/root:/bin/bash
[root@localhost data]# sed -n '/^root/ s/^/#/p' passwd
#root:x:0:0:root:/root:/bin/bash
#注释fstab文件中的swap行
[root@localhost data]# sed -n '/swap/ s/^/#/p' /etc/fstab
#/dev/mapper/centos-swap swap swap defaults 0 0
[root@localhost data]# sed -n 's/.*swap.*/#&/p' /etc/fstab
#/dev/mapper/centos-swap swap swap defaults 0 0
[root@localhost data]#
#使用脚本执行sed命令
[root@localhost data]# vim script.sed
1,10 s/^/#/
#1-10行注释
/root/ s/$/#/
#包括root的行后面加上井号
如同只用了多次-e操作?
#保存替换的内容到新的文件中
[root@localhost data]# sed -n 's/root/admin/gp' passwd >out1.txt
[root@localhost data]# cat out1.txt
admin:x:0:0:admin:/admin:/bin/bash
operator:x:11:0:operator:/admin:/sbin/nologin
[root@localhost data]# sed -n 's/root/admin/w out2.txt' passwd
[root@localhost data]# cat out2.txt
admin:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/admin:/sbin/nologin
[root@localhost data]#
sed 's9\945\9\99\98\939g' 1.txt #这行命令是谁替换谁
9\945\9\99\98\939
#前面说过,分隔符是三个一样的字符就可以,可以看出分隔符是9而\是转义字符
#去掉三个没有转义的9就是下面的样子
94599 9893
#所以是94599替换成9893
#要实现这两种内容的转变
[root@localhost data]# echo 123456
123456
[root@localhost data]# echo '<123456>'
<123456>
#前后交换
[root@localhost data]# echo old_new |sed -r 's#(^.*)_(.*$)#\2_\1#g'
new_old
(old)_(new)
? ? ? ? ?\1_\2?
[root@localhost data]# sed '1c zhangsan996' users.txt
zhangsan996
2,lisi
3,wangwu
4,zhaoliu
5,qianqi
6,zhuba
#使用y转换
[root@localhost data]# sed 'y/zhangsan/zzzzzzzz/' users.txt
1,zzzzzzzz
2,lizi
3,wzzzwu
4,zzzoliu
5,qizzqi
6,zzubz
[root@localhost data]# sed 'y/zhangsan/zzzzzzz/' users.txt
sed:-e 表达式 #1,字符 19:“y”命令的字符串长度不同
[root@localhost data]#
#使用tr替换
[root@localhost data]# cat users.txt |tr 'zhangsan' 'zzzzzzzz'
1,zzzzzzzz
2,lizi
3,wzzzwu
4,zzzoliu
5,qizzqi
6,zzubz
[root@localhost data]# cat users.txt |tr 'zhangsan' 'zzzz'
1,zzzzzzzz
2,lizi
3,wzzzwu
4,zzzoliu
5,qizzqi
6,zzubz
?
2.5?sed-剪切H-粘贴G
#将1-3行剪切并粘贴到最后
[root@localhost data]# sed '1,3 {H;d};$G' users.txt
4,zhaoliu
5,qianqi
6,zhuba
1,zhangsan
2,lisi
3,wangwu
总结
sed执行多条命令的方式:
sed -n -e '命令1' -e '命令2' 文件
sed -n -e '命令1;命令2' 文件
sed -n '
命令1
命令2
......
' 文件
?sed对指定行操作:
- 以数字形式表示行区间
- 用字符串来过滤行
s/OLD/NEW/2? 代表对每行第二个匹配到的字符串进行替换
? ? ? ? ? ? ? ? ? ? ?g? 代表对每行所有能匹配到的字符进行替换
? ? ? ? ? ? ? ? ? ? ?p? ?可以结合-n?选项只打印替换的行内容
? ? ? ? ? ? ? ? ? ? ?w? ?可以把替换的行内容保存到指定的文件中
n,m s/OLD/NEW/
/字符串+正则/ s/OLD/NEW
s/^/添加的字符/ 行首添加内容
s/$/添加的字符/ 行尾添加内容
sed -f 文件 可以在文件中定义多条操作规则
sed替换命令的字符串分隔符,就看s后面跟的字符,3个分隔符要保持一致,如果遇到跟分隔符相同的字符则需要使用\来转义
sed -i?可以直接修改文件内容,操作前建议先验证命令和备份目标文件
增删改查
删d
改s(字符串替换) c(整行替换) y(对应字符串替换,效率类似tr)
查p
增 a(在行后)i(在行前)r(在行后读入文件内容)
复制粘贴 H;G
|