Linux文本三剑客之sed编辑器(永远温柔永远清醒)

目录

前言

一、特点及格式

 二、sed核心应用

2.1 sed-查找打印p

2.2 sed-删除d

2.3 sed-增加air

2.4 sed-替换scy

2.5 sed-剪切H-粘贴G

总结


扫描二维码关注公众号,回复: 14235441 查看本文章

前言

我们将/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"

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

替换格式
s###g
s///g
sAAAg
替换标记 含义
数字 表明新字符串将替换第几处匹配的地方
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 

  • c/y
[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对指定行操作:

  1. 以数字形式表示行区间
  2. 用字符串来过滤行

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

猜你喜欢

转载自blog.csdn.net/qq_42327944/article/details/124295190
今日推荐