文章目录
行编辑器sed介绍
sed是一个强大而简单的文本解析转换工具,可以读取文本,并根据指定的条件对文本内容进行编辑(增加,删除,替换,添加,移动等)最后输出所以行或仅输出处理的某些行。
sed也可以在无交互的情况下实现相当复杂的文本处理操作,被广泛应用于shell脚本中,用以完成各种自动化处理任务
1、工作流程
读取:sed从输入流 (文件、管道、标准输入) 中读取一行内容并存储到临时的缓冲区中(又称模式空间,pattern space)
执行:默认情况下,所有的sed命令都在模式空间中顺序地执行,除非指定了行的地址,否则sed命令将会在所有的行上依次执行
显示:发送修改后的内容到输出流。在发送数据后,模式空间将会被清空。在所有的文件内容都被处理完成之前,上述过程将重复执行,直至所有内容被处理完
注意:默认情况下,所有的 sed 命令都是在模式空间内执行的,因此输入的文件并不会发生任何变化,除非是用重定向存储输出。
2.基本用法
sed [选项] ‘操作’ 参数
其中,“参数”是指操作的目标文件,当存在多个操作对象时,文件之间用逗号分隔。
sed [选项] -f scriptfile 参数
而scriptfile 表示脚本文件,需要用“-f”选项指定,当脚本文件出现在目标文件之前时,表示通过指定的脚本文件来处理输入的目标文件
3.常用选项
**-n 不输出模式空间内容到屏幕,即不自动打印,仅显示处理后的结果**
-e 表示用指定命令或者脚本来处理输入的文本文件
-f FILE 从指定文件中读取编辑脚本
**-r, -E 使用扩展正则表达式
-i 直接编辑文本文件
-i.bak 备份文件并原处编辑**
-s 将多个文件视为独立文件,而不是单个连续的长文件流
4.常见的sed操作指令
**“操作”**用于指定对文件操作的动作行为,也就是 sed 的命令。通常情况下是采用的“[n1[,n2]]”操作参数的格式。n1、n2 是可选的,不一定会存在,代表选择进行操作的行数,如操作需要在 5~20 行之间进行,则表示为“5,20 动作行为”。常见的操作包括以下几种。
p 打印,如果同时指定行,表示打印指定行,如果不指定行,则表示打印所有内容,如果有非打印字符,则以 ASCII 码输出。其通常与“-n”选项一起使用。
Ip 忽略大小写输出
d 删除模式空间匹配的行,并立即启用下一轮循环
a 增加,在当前行下面增加一行指定内容;[\]text 在指定行后面追加文本,支持使用\n实现多行追加
i 插入,在选定行上面插入一行指定内容;[\]text 在行前面插入文本
c 替换,将选定行替换为指定内容;[\]text 替换行为单行或多行文本
s 替换,替换指定字符;s 的动作可以搭配正规表示法!例如 1,20s/old/new/g
y 字符转换。
w file 保存模式匹配的行至指定文件
r file 读取指定文件的文本至模式空间中匹配到的行后
= 为模式空间中的行打印行号
! 模式空间中匹配行取反处理
q 结束或退出sed
Sed用法示例
直接输入sed会出现sed用法
[root@yzq mnt]#sed
sed ’ ’ 不加选项,不加操作,不加参数默认将输入内容打印出来
[root@yzq mnt]#sed ''
a
a
sd
sd
pp
pp
单独加上参数,查看文件内容
[root@yzq mnt]#sed '' txt
1 www.kgc.com
2 mail.kgc.com
3 ftp.kgc.com
4 linux.kgc.com
5 blog.kgc.com
sed带有自动打印功能,p操作又再打印一遍
[root@yzq mnt]#sed 'p' txt
1 www.kgc.com
1 www.kgc.com
2 mail.kgc.com
2 mail.kgc.com
3 ftp.kgc.com
3 ftp.kgc.com
4 linux.kgc.com
4 linux.kgc.com
5 blog.kgc.com
5 blog.kgc.com
-n:只显示处理后的结果,但是不修改文件原本的内容
只p打印
[root@yzq mnt]#sed -n 'p' txt
1 www.kgc.com
2 mail.kgc.com
3 ftp.kgc.com
4 linux.kgc.com
5 blog.kgc.com
指定行数打印输出(可以指定单行或多行)
指定打印某行
[root@yzq mnt]#sed -n '2p' txt
2 mail.kgc.com
[root@yzq mnt]#sed -n 3p txt
3 ftp.kgc.com
打印3-5行
[root@yzq mnt]#sed -n '3,5p' txt
3 ftp.kgc.com
4 linux.kgc.com
5 blog.kgc.com
打印某行和之后几行
[root@yzq mnt]#sed -n '2,+2p' txt
2 mail.kgc.com
3 ftp.kgc.com
4 linux.kgc.com
打印某些行
打印奇数行,1表示起始行,~2表示步长
[root@yzq mnt]#sed -n '1~2p' txt
1 www.kgc.com
3 ftp.kgc.com
5 blog.kgc.com
输出所有奇数行,n 表示读入下一行资料,输出1-5行的奇数行可用‘1,5{p;n}’表示
[root@yzq mnt]#sed -n 'p;n' txt
1 www.kgc.com
3 ftp.kgc.com
5 blog.kgc.com
输出所有偶数行,n 表示读入下一行资料
[root@yzq mnt]#sed -n 'n;p' txt
2 mail.kgc.com
4 linux.kgc.com
输出第3行至行尾的偶数行
[root@yzq mnt]#sed -n '3,${n;p}' test
antlr-runtime-3.4.jar
archaius-core-0.7.6.jar
aspectjweaver-1.9.5.jar
bcprov-jdk15-1.46.jar
checker-compat-qual-2.5.5.jar
打印第一行和第三行
[root@yzq mnt]#sed -n '1p;3p' txt
1 www.kgc.com
3 ftp.kgc.com
匹配内容打印行
//中间输入需要匹配的内容,输出包含ftp的行
[root@yzq mnt]#sed -n '/ftp/p' txt
3 ftp.kgc.com
输出从第三行开始,一直到第一个包含5的行
[root@yzq mnt]#sed -n '3,/5/p' 1.txt
3
4
5
输出一共3个1为止的行,即找到3个1为止
[root@yzq mnt]#sed -n '/1/,3p' 1.txt
1
2
3
10
11
还可以匹配正则表达式
输出以root开头的行到以b开头的行(不是只输出这两行)
[root@yzq mnt]#sed -n '/^root/,/^b/p' /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
输出包含内容的行所在的行号,等号(=)用来输出行号
[root@yzq mnt]#sed -n '/run/=' test
4
[root@yzq mnt]#sed -n '=' test
1
2
3
4
5
6
7
8
9
10
11
12
输出包含单词linux 的行,<、>代表单词边界
[root@yzq mnt]#sed -n '/\<linux\>/p' txt
4 linux.kgc.com
删除
d删除
删除第三行的内容
[root@yzq mnt]#sed -n '3d;p' txt
1 www.kgc.com
2 mail.kgc.com
4 linux.kgc.com
5 blog.kgc.com
删除3-5行的内容
[root@yzq mnt]#sed -n '3,5d;p' txt
1 www.kgc.com
2 mail.kgc.com
删除包含linux的行,第四行被删除
[root@yzq mnt]#sed -n '/linux/d;p' txt
1 www.kgc.com
2 mail.kgc.com
3 ftp.kgc.com
5 blog.kgc.com
删除不包含linux的行,用!取反
!在指定内容的后面
[root@yzq mnt]#sed -n '/linux/!d;p' txt
4 linux.kgc.com
删除小写字母开头的行
[root@yzq mnt]#cat 2.txt
1 www.baidu.com
2 www.google.com
3 www.jd.com
4 www.tmall.com
5 www.taobao.com
baidu
google
jd
tmall
taobao
[root@yzq mnt]#sed -n '/^[a-z]/d;p' 2.txt
1 www.baidu.com
2 www.google.com
3 www.jd.com
4 www.tmall.com
5 www.taobao.com
删除数字开头的行
[root@yzq mnt]#sed -n '/^[0-9]/d;p' 2.txt
baidu
google
jd
tmall
taobao
删除以m结尾的行
[root@yzq mnt]#sed -n '/m$/d;p' 2.txt
baidu
google
jd
tmall
taobao
删除所有空行
注意: 若是删除重复的空行,即连续的空行只保留一个, 执行“ sed –e ‘/^KaTeX parse error: Expected group after ‘^’ at position 6: /{n;/^̲/d}’test.txt”命令即可实现。其效果与“cat -s test.txt”相同,n 表示读下一行数据。
[root@yzq mnt]#sed -n '/^$/d;p' 2.txt
1 www.baidu.com
2 www.google.com
3 www.jd.com
4 www.tmall.com
5 www.taobao.com
baidu
google
jd
tmall
taobao
s///替换删除
可以用替换来实现删除
将www替换为空格,即可达到删除的效果
[root@yzq mnt]#sed 's/www//' 2.txt
1 .baidu.com
2 .google.com
3 .jd.com
4 .tmall.com
5 .taobao.com
baidu
google
jd
tmall
taobao
将每行第一个w删除(替换为空格)
/后面跟个数代表替换几个,/g代表全部替换
[root@yzq mnt]#sed 's/w//1' 2.txt
1 ww.baidu.com
2 ww.google.com
3 ww.jd.com
4 ww.tmall.com
5 ww.taobao.com
baidu
google
jd
tmall
taobao
[root@yzq mnt]#sed 's/w//g' 2.txt
1 .baidu.com
2 .google.com
3 .jd.com
4 .tmall.com
5 .taobao.com
baidu
google
jd
tmall
taobao
删除所有特殊字符
[root@yzq mnt]#sed 's/[^a-Z0-9]//g' 2.txt
1wwwbaiducom
2wwwgooglecom
3wwwjdcom
4wwwtmallcom
5wwwtaobaocom
baidu
google
jd
tmall
taobao
添加
a:在行后添加
在第二行后面添加一行ww
[root@yzq mnt]#sed '2aww' 2.txt
1 www.baidu.com
2 www.google.com
ww
3 www.jd.com
4 www.tmall.com
5 www.taobao.com
baidu
google
jd
tmall
taobao
在第二行后添加多行 \n表示换行
[root@yzq mnt]#sed '2aw\nww' 2.txt
1 www.baidu.com
2 www.google.com
w
ww
3 www.jd.com
4 www.tmall.com
5 www.taobao.com
baidu
google
jd
tmall
taobao
在百度下面添加一行1
[root@yzq mnt]#sed '/baidu/a1' 2.txt
1 www.baidu.com
1
2 www.google.com
3 www.jd.com
4 www.tmall.com
5 www.taobao.com
baidu
1
google
jd
tmall
taobao
i在行前添加
i同a用法相同,不过i是在上面一行添加
在百度上一行添加1
[root@yzq mnt]#sed '/baidu/i1' 2.txt
1
1 www.baidu.com
2 www.google.com
3 www.jd.com
4 www.tmall.com
5 www.taobao.com
1
baidu
google
jd
tmall
taobao
操作c整行替换
用c来替换,将选定行替换为指定内容
将第二行替换为google
[root@yzq mnt]#sed '2cgoogle' 2.txt
1 www.baidu.com
google
3 www.jd.com
4 www.tmall.com
5 www.taobao.com
baidu
google
jd
tmall
taobao
针对字符串替换
上面说过s///可以删除就是替换的原理,只不过是替换成空格
将全文baidu替换为qq
[root@yzq mnt]#sed 's/baidu/qq/g' 2.txt
1 www.qq.com
2 www.google.com
3 www.jd.com
4 www.tmall.com
5 www.taobao.com
qq
google
jd
tmall
taobao
s///最后一个/后面没有操作默认替换第一个
[root@yzq mnt]#sed 's/w/x/' 2.txt
1 xww.baidu.com
2 xww.google.com
3 xww.jd.com
4 xww.tmall.com
5 xww.taobao.com
baidu
google
jd
tmall
taobao
全文注释
[root@yzq mnt]#sed 's/^/#/g' 2.txt
#1 www.baidu.com
#2 www.google.com
#3 www.jd.com
#4 www.tmall.com
#5 www.taobao.com
#baidu
#google
#jd
#tmall
#taobao
指定某几行注释
[root@yzq mnt]#sed '1,3s/^/#/g' 2.txt
#1 www.baidu.com
#2 www.google.com
#3 www.jd.com
4 www.tmall.com
5 www.taobao.com
baidu
google
jd
tmall
taobao
包含baidu的行注释
[root@yzq mnt]#sed '/baidu/s/^/#/g' 2.txt
#1 www.baidu.com
2 www.google.com
3 www.jd.com
4 www.tmall.com
5 www.taobao.com
#baidu
google
jd
tmall
taobao
选项-i使修改的数据生效
以上的修改都是保存在sed临时的缓冲区中,并不是真实生效的,只有加上-i选项才能使修改生效
[root@yzq mnt]#sed '/baidu/s/^/#/g' 2.txt
#1 www.baidu.com
2 www.google.com
3 www.jd.com
4 www.tmall.com
5 www.taobao.com
#baidu
google
jd
tmall
taobao
[root@yzq mnt]#cat 2.txt
1 www.baidu.com
2 www.google.com
3 www.jd.com
4 www.tmall.com
5 www.taobao.com
baidu
google
jd
tmall
taobao
[root@yzq mnt]#sed -i '/baidu/s/^/#/g' 2.txt
[root@yzq mnt]#cat 2.txt
#1 www.baidu.com
2 www.google.com
3 www.jd.com
4 www.tmall.com
5 www.taobao.com
#baidu
google
jd
tmall
taobao
直接对文件修改有可能会出错,这时候可以使用-i.bak先备份再修改数据
[root@yzq mnt]#cat txt
1 www.kgc.com
2 mail.kgc.com
3 ftp.kgc.com
4 linux.kgc.com
5 blog.kgc.com
[root@yzq mnt]#sed -i.bak '2d' txt
[root@yzq mnt]#ls
1.txt 4.txt Btxt Dtxt shuzu
1.txtn atxt ctxt expect.sh test
2.txt Atxt Ctxt nginx.access.log-2021013 txt
3.txt btxt dtxt passwd txt.bak
[root@yzq mnt]#cat txt
1 www.kgc.com
3 ftp.kgc.com
4 linux.kgc.com
5 blog.kgc.com
[root@yzq mnt]#cat txt.bak
1 www.kgc.com
2 mail.kgc.com
3 ftp.kgc.com
4 linux.kgc.com
5 blog.kgc.com
迁移符合条件的文本
迁移文本的参数
H: 复制到剪贴板;
g、G: 将剪贴板中的数据覆盖/追加至指定行;
w:保存为文件;
r:读取指定文件;
a:追加指定内容。
I,i 忽略大小写
把文本第一行复制到最后
G追加,$末尾
[root@yzq mnt]#sed '/www/{H};$G' txt.bak
1 www.kgc.com
2 mail.kgc.com
3 ftp.kgc.com
4 linux.kgc.com
5 blog.kgc.com
1 www.kgc.com
把文本第一行剪切到最后
{;}用于多个操作,d:删除,$:末尾,g:覆盖
[root@yzq mnt]#sed '/www/{H;d};$g' txt.bak
2 mail.kgc.com
3 ftp.kgc.com
4 linux.kgc.com
1 www.kgc.com
[root@yzq mnt]#cat txt.bak
1 www.kgc.com
2 mail.kgc.com
3 ftp.kgc.com
4 linux.kgc.com
5 blog.kgc.com
把1-3行剪切到第五行后面
[root@yzq mnt]#sed '1,3{H;d};5G' txt.bak
4 linux.kgc.com
5 blog.kgc.com
1 www.kgc.com
2 mail.kgc.com
3 ftp.kgc.com
将包含www的行保存到www文件中
[root@yzq mnt]#sed '/www/w www' txt.bak
1 www.kgc.com
2 mail.kgc.com
3 ftp.kgc.com
4 linux.kgc.com
5 blog.kgc.com
[root@yzq mnt]#cat www
1 www.kgc.com
从www文件中读取文件到包含www的行下面
将www文件中的内容输出到包含www的行的下面
[root@yzq mnt]#sed '/www/r www' txt.bak
1 www.kgc.com
1 www.kgc.com
2 mail.kgc.com
3 ftp.kgc.com
4 linux.kgc.com
5 blog.kgc.com
sed分组
sed使用扩展正则分组提取网卡中IP地址
-r使用扩展正则,使用s/ / /将一行文件分组,而()中的成组,\1代表提取第一组
s/.inet (.) net.*/\1/p中.*inet表示需要提取IP之前的字符,inet前面的空格不知道几个,直接用.*代替,
而IP之前的字符为netmask开头,我们也不需要知道具体,只需用net.*代表IP之后的字符,而要提取的内容为()中的,我们只需用.*匹配即可,分割以空格隔开,只有()中的为组,这里我们提取第一组 \1表示的是第一组,即()中的字符,最后p打印出来即可
[root@yzq mnt]#ifconfig ens33
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.28.10 netmask 255.255.255.0 broadcast 192.168.28.255
inet6 fe80::c5af:9d75:a8f6:7c70 prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:c6:78:5e txqueuelen 1000 (Ethernet)
RX packets 22628 bytes 20936910 (19.9 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 8362 bytes 690252 (674.0 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
[root@yzq mnt]#ifconfig ens33 | sed -nr 's/.*inet (.*) net.*/\1/p'
192.168.28.10
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/76550.html