第14章 Linux Sed
三剑客命令-sed
1.sed介绍
sed是Stream Editor(字符流编辑器)的缩写,简称流编辑器.
sed就像车间的流水线一样,需要处理的字符就是流水线上的原材料,经过sed处理后,就变成了货物。
sed的应用场景主要如下:
1.查找和过滤文件内容
2.替换文件内容
3.脚本里可以用来检查输入是否纯英文或者纯数字
2.sed命令使用
命令作用:
sed [options] [sed-commands] [input-file]
sed [选项] [sed命令] [输入文件]
执行过程:
1.sed从文件或管道读取一行,处理一行,输出一行
2.再读取一行.再处理一行.在输出一行
常用选项:
-n 取消默认的sed软件的输出,常与sed命令的p连用
-e 一行命令语句可以执行多条sed命令
-r 使用正则拓展表达式,默认情况sed只识别基本正则表达式
-i 直接修改文件内容,而不是输出终端,如果不使用-i选项sed软件只是修改在内存中的数据,并不影响磁盘上的文件
常用命令:
a 追加,在指定行后添加一行或多行文本
c 取代指定的行
d 删除指定的行
i 插入,在指定的行前添加一行或多行文本
p 打印内容,通常和-n一起使用
s 取代 s#要替换的内容#替换的内容#g
特殊符号:
! 对指定行以外的所有行应用命令
= 打印当前行号
; 实现一行命令语句可以执行多条sed命令
3.sed练习-查找
sed查找主要是用到-n和p的组合,-n用来取消默认输出,p表示只显示匹配的行。
测试文本
cat > luffy.txt << EOF
I am oldzhang !
I teach linux.
testtt0aaaasssabcc788ayyytt
#I like swimming, football, basketball, video games
I like ChaShao TaiQiu
#my blog is https://www.cnblogs.com/alaska/
my site is https://www.jianshu.com/u/ee1c7fcea5b0
#my-qq is 526195417.
my_phone is 1532000233111112.
EOF
查找单行
查找第2行
[root@centos7 ~]# sed -n '2p' luffy.txt
I teach linux.
查找多行
查询第2行到第3行
[root@centos7 ~]# sed -n '2,3p' luffy.txt
I teach linux.
testtt0aaaasssabcc788ayyytt
关键词查找
按字包含Cha关键词的行
[root@centos7 ~]# sed -n '/Cha/p' luffy.txt
I like ChaShao TaiQiu
关键词查找
查找以I开头的行
[root@centos7 ~]# sed -n '/^I/p' luffy.txt
I am oldzhang !
I teach linux.
I like ChaShao TaiQiu
按关键词范围查找
查找oldzhang到Cha中间所有的行
[root@centos7 ~]# sed -n '/oldzhang/,/Cha/p' luffy.txt
I am oldzhang !
I teach linux.
testtt0aaaasssabcc788ayyytt
#I like swimming, football, basketball, video games
I like ChaShao TaiQiu
查找第3行到Cha关键词的行
[root@centos7 ~]# sed -n '3,/Cha/p' luffy.txt
testtt0aaaasssabcc788ayyytt
#I like swimming, football, basketball, video games
I like ChaShao TaiQiu
查找包含ball和linux的行,需要用到扩展正则
[root@centos7 ~]# sed -rn '/ball|linux/p' luffy.txt
I teach linux.
#I like swimming, football, basketball, video games
4.sed练习-增加
增加使用的是a与i命令,分别为关键行前添加或者后面添加
单行增加
在第2行后面新添加一行 good good study day day up
[root@centos7 ~]# sed '2a good good study day day up' luffy.txt |head -4
I am oldzhang !
I teach linux.
good good study day day up
testtt0aaaasssabcc788ayyytt
在第2行前面新添加一行 good good study day day up
[root@centos7 ~]# sed '2i good good study day day up' luffy.txt |head -4
I am oldzhang !
good good study day day up
I teach linux.
testtt0aaaasssabcc788ayyytt
多行增加
在第2行后面新添加两行文本 good good study day day up; you can you up
[root@centos7 ~]# sed '2a good good study day day up\nyou can you up' luffy.txt |head -5
I am oldzhang !
I teach linux.
good good study day day up
you can you up
testtt0aaaasssabcc788ayyytt
在3行前面添加一行aaaaaaaaaaa
[root@centos7 ~]# sed '3i aaaaaaaaaaa' luffy.txt |head -4
I am oldzhang !
I teach linux.
aaaaaaaaaaa
testtt0aaaasssabcc788ayyytt
5.sed练习-替换
替换说明
sed的替换功能非常强大,也是使用sed最多的用途。
默认sed替换并不会真正的修改文件,如果想把修改的内容写入到文件里,需要添加-i参数
命令语法:
sed '[地址范围|模式范围] s#[被替换的关键词]#[需要替换成的关键词]#[替换标志]' [输入文件]
命令解释:
1.[地址范围|模式范围]:可选选项,如果没有指定,sed软件将在所有行上进行替换。
2."s" 即执行替换命令substitute
3.被替换的字符串,可以是一个正则表达式
4.替换后的字符串,只能是一个具体的内容
5.替换标志:可选选项
- 全局标志g
- 数字标志(1,2,3...)
- 打印标志p
- 写标志w
- 忽略大小写标志i
- 执行命令标志e
根据需要可以把一个或多个替代标志组合起来使用。
测试文本
cat > person.txt <<EOF
101,Zhangya,CEO
102,BanZhang,CTO
103,CKman,COO
104,Mr.Sheng,UFO
105,GuanRu,CXO
EOF
指定关键词替换
将CXO替换为XO
#1.直接关键词替换
[root@centos7 ~]# sed 's#CXO#XO#g' person.txt
101,Zhangya,CEO
102,BanZhang,CTO
103,CKman,COO
104,Mr.Sheng,UFO
105,GuanRu,XO
#2.如果只想显示被替换的行,可以使用-n结合p一起使用
[root@centos7 ~]# sed -n 's#CXO#XO#gp' person.txt
105,GuanRu,XO
将所有的a替换为A
[root@centos7 ~]# sed 's#a#A#g' person.txt
101,ZhAngyA,CEO
102,BAnZhAng,CTO
103,CKmAn,COO
104,Mr.Sheng,UFO
105,GuAnRu,CXO
只将第一次匹配上的a替换为A
[root@centos7 ~]# sed 's#a#A#' person.txt
101,ZhAngya,CEO
102,BAnZhang,CTO
103,CKmAn,COO
104,Mr.Sheng,UFO
105,GuAnRu,CXO
只将第二次匹配上的a替换为A
[root@centos7 ~]# sed 's#a#A#2g' person.txt
101,ZhangyA,CEO
102,BanZhAng,CTO
103,CKman,COO
104,Mr.Sheng,UFO
105,GuanRu,CXO
忽略大小写替换 将e和E替换为F
[root@centos7 ~]# sed -r 's#e#F#gi' person.txt
101,Zhangya,CFO
102,BanZhang,CTO
103,CKman,COO
104,Mr.ShFng,UFO
105,GuanRu,CXO
指定行进行替换
将第1行文本替换为200,DongLai,CEO
#1.第一种方法,使用s###g替换
[root@centos7 ~]# sed '1s#.*#200,DongLai,CEO#g' person.txt
200,DongLai,CEO
102,BanZhang,CTO
103,CKman,COO
104,Mr.Sheng,UFO
105,GuanRu,CXO
#2.第二种方法,直接替换指定行内容
[root@centos7 ~]# sed '1c 200,DongLai,CEO' person.txt
200,DongLai,CEO
102,BanZhang,CTO
103,CKman,COO
104,Mr.Sheng,UFO
105,GuanRu,CXO
指定关键词分组替换
CEO和数字替换位置
[root@centos7 ~]# sed -r 's#(.*),(.*),(.*)#\3,\2,\1#g' person.txt
CEO,Zhangya,101
CTO,BanZhang,102
COO,CKman,103
UFO,Mr.Sheng,104
CXO,GuanRu,105
将中间的名字去掉,变成格式:101,CEO
[root@centos7 ~]# sed -r 's#(.*),.*,(.*)#\1,\2#g' person.txt
101,CEO
102,CTO
103,COO
104,UFO
105,CXO
将第一个逗号替换为 - 第二个逗号替换为 _ 举例:101-DongLai_CEO
#1.第一种方法:分组替换
[root@centos7 ~]# sed -r 's#(.*)(,)(.*)(,)(.*)#\1-\3_\5#g' person.txt
101-Zhangya_CEO
102-BanZhang_CTO
103-CKman_COO
104-Mr.Sheng_UFO
105-GuanRu_CXO
#2.第二种方法:命令拼接
[root@centos7 ~]# sed 's#,#-#' person.txt|sed 's#,#_#g'
101-Zhangya_CEO
102-BanZhang_CTO
103-CKman_COO
104-Mr.Sheng_UFO
105-GuanRu_CXO
6.sed练习-删除
删除指定的行
删除第2行的内容
[root@centos7 ~]# sed '2d' person.txt
101,Zhangya,CEO
103,CKman,COO
104,Mr.Sheng,UFO
105,GuanRu,CXO
删除多行
删除第2和第5行
[root@centos7 ~]# sed '2d;5d' person.txt
101,Zhangya,CEO
103,CKman,COO
104,Mr.Sheng,UFO
删除第2行到第4行
[root@centos7 ~]# sed '2,4d' person.txt
101,Zhangya,CEO
105,GuanRu,CXO
使用步长删除 隔几行删除,本行也算一行
1~2,表示删除从第一行开始,隔一行删一行
[root@centos7 ~]# sed '1~2d' person.txt
102,BanZhang,CTO
104,Mr.Sheng,UFO
删除指定行之后的N行
[root@centos7 ~]# sed '1,+2d' person.txt
104,Mr.Sheng,UFO
105,GuanRu,CXO
取反删除 只保留第1和第2行
[root@centos7 ~]# sed '1,2!d' person.txt
101,Zhangya,CEO
102,BanZhang,CTO
删除关键词的行
删除包含关键词的行
[root@centos7 ~]# sed '/UFO/d' person.txt
101,Zhangya,CEO
102,BanZhang,CTO
103,CKman,COO
105,GuanRu,CXO
正则表达式删除 删除名字里包含两个大写字母的行 比如BanZhang
[root@centos7 ~]# sed -r '/.*[A-Z]+[a-z]+[A-Z]+.*/d' person.txt
101,Zhangya,CEO
103,CKman,COO
104,Mr.Sheng,UFO
删除第一个关键词与第二个关键词之间所有的行
[root@centos7 ~]# sed '/CTO/,/UFO/d' person.txt
101,Zhangya,CEO
105,GuanRu,CXO
其他替换标志
替换标志 含义
\l 在替换字符中shiyong\l标志时,他会把紧跟其后面的1个字符当做小写字符来处理
\L 在替换字符中shiyong\L标志时,他会把后面所有的字符都当作小写字符来处理
\u 在替换字符中使用\u标志时,他会把紧其后面的1个字符当作大写字符来处理
\U 在替换字符中使用\U标志时,他会把后面所有的字符都当作大写字符来处理。
\E 需要\U或\L一起使用,他将关闭\U或\L的功能
7. 生产实战
提取IP地址 尽可能多的方法
ifconfig eth0|sed -rn 's#.*t (.*) n.*#\1#p'
cat /etc/sysconfig/network-scripts/ifcfg-eth0|sed -nr '/IPADDR/s#.*=(.*)#\1#p'
修改IP地址 将网卡配置文件里ip地址修改为192.168.1.1
cp /etc/sysconfig/network-scripts/ifcfg-eth0 ifcfg-eth0
sed -r '/IPADDR/s#IPADDR=(.*)#IPADDR=192.168.1.1#g' ifcfg-eth0
sed -r '/IPADDR/c IPADDR=192.168.1.1' ifcfg-eth0
替换nginx配置文件运行用户为www
cp /etc/nginx/nginx.conf .
sed -rn 's#user nginx#user www#p' nginx.conf
sed -rn '/^user/c user www;' nginx.conf
sed -rn 's#user .*;#user www;#p' nginx.conf
将/etc/passwd 第一列取出来
sed -r 's#(^[a-Z0-9-]+).*#\1#' /etc/passwd
sed 's#:.*##g' /etc/passwd
sed 's#:x:.*$##g' /etc/passwd
sed -r 's#(.):.*$#\1#g' /etc/passwd
sed -r 's#(^[^:]+).*$#\1#g' /etc/passwd
sed -r 's#(^.*):x.*$#\1#g' /etc/passwd
sed -r 's#(^[a-zA-Z0-9#-]+).*$#\1#g' /etc/passwd
将/etc/passwd 用户名列,UID列和GID列取出来
sed -r 's#^(.*):.*:(.*):(.*):.*:.*:.*#\1:\2:\3#g' /etc/passwd
将/etc/passwd 第一列和最后一列位置调换
sed -r 's#(^[a-zA-Z0-9#-]+)(:.*:)(.*$)#\3\2\1#g' /etc/passwd
sed -r 's#(^[^:]+)(:.*:)(.*$)#\3\2\1#g' /etc/passwd
批量重命名文件
touch stu_102999_\{1..5\}_finished.jpg
ls|sed -r 's#(.*)_(.*)_(.*)_(.*)(\..*)#\1_\2_\3\5#g'
ls|sed -r 's#(.*)_(.*)_(.*)_(.*)(\..*)#mv & \1_\2_\3\5#g'
ls|sed -r 's#(.*)_(.*)_(.*)_(.*)(\..*)#mv & \1_\2_\3\5#g'|bash
ls *.jpg|sed -r 's#(^.*)_finished.*$#mv & \1.jpg#'
ls stu*|xargs -n1|sed -r "s#(^.*[1-9]).*(.jpg)#mv & \1\2#g"
ls|awk -F "_finished" '\{print "mv",$0,$1$2\}'
rename "_finished" "" *.jpg
更改文件同时备份
[root@centos7 ~]# sed -i.bak 's#CEO#CCO#g' person.txt
[root@centos7 ~]# ll person.txt*
-rw-r--r-- 1 root root 79 4月 15 08:14 person.txt
-rw-r--r-- 1 root root 79 4月 14 19:43 person.txt.bak
删除阿里源里包含aliyunc的行
#配置国内yum基础源
wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
#配置国内yum拓展源
wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
#删除阿里源里的内网链接
sed -i '/aliyuncs/d' /etc/yum.repos.d/*.repo
从日志里取IP地址
8.sed的坑
乱放p的坑
#号的坑
更新: 2024-09-21 19:55:46