Linux三剑客SED
Linux三剑客为 sed awk grep 本文会讲解到sed在实践中的常用的多种方式,并举例演示,让你更好理解sed命令
sed版本
[root@oldboy ~]# sed --version #→ sed软件版本
GNU sed version 4.2.1
sed 语法格式
sed [options] [sed-commands] [input-file]
sed [选项] [sed命令] [输入文件]
说明:
1. 注意sed和后面的选项之间至少有一个空格。
2. 为了避免混淆,本文称呼sed为sed软件。sed-commands(sed命令)是sed软件内置的一些命令选项,为了和前面的options(选项)区分,故称为sed命令。
3. sed-commands既可以是单个sed命令,也可以是多个sed命令组合。
4. input-file(输入文件)是可选项,sed还能够从标准输入如管道获取输入。
sed命令的执行流程图
n和p 需要同时出现 如果有n 后面一定要加p 原因时 -n 取消默认输出。 p 是打印输出内容。 一般都会成对出现。
概括流程:Sed软件从文件或管道中读取一行,处理一行,输出一行;再读取一行,再处理一行,再输出一行……
模式空间:sed软件内部的一个临时缓存,用于存放读取到的内容。
实验准备
简单介绍了sed,现在来一起做实验,创建实验文本
[root@oldboy ~]# cat 1.txt
101,oldboy,CEO
102,zhangyao,CTO
103,Alex,COO
104,yy,CFO
105,feixue,CIO
sed 增删改查案例
sed 增
sed可以通过 a 追加文本 i 插入文本
我记忆方式是 i前 a后 也就是 i会插入到指定行前,替换指定行,指定行会在替换的行下方
a 增加的内容会在 指定行的下方,下面用例子说明
-n 取消默认输出
-r 支持正则表达式
-p 打印
-e 多项编辑
-i.bak 修改后备份
s 搜索一次
sg 搜索全局
# # # : s#替换前#替换后#g
/ / / : 与###一样
a 案例:
插入内容到 2a 也就是第二行的下方
[root@leilei ~]# sed '2a 106,dandan,CSO' 1.txt
101,oldboy,CEO
102,zhangyao,CTO
106,dandan,CSO
103,Alex,COO
104,yy,CFO
105,feixue,CIO
多行插入:
[root@leilei ~]# sed '2a 106,dandan,CSO \
> 107,bingbing,CCO' 1.txt
101,oldboy,CEO
102,zhangyao,CTO
106,dandan,CSO #→第2种写法 将多行内容插入到第二行的后面
107,bingbing,CCO
103,Alex,COO
104,yy,CFO
105,feixue,CIO
i案例:
i会插入成指定行,占用该行的内容会被下移
[root@leilei ~]# sed '2i 106,dandan,CSO' 1.txt
101,oldboy,CEO
106,dandan,CSO #插入到第二行,而第二行内容会被移动到下一行
102,zhangyao,CTO
103,Alex,COO
104,yy,CFO
105,feixue,CIO
多行插入:
[root@leilei ~]# sed '2i 106,dandan,CSO\n107,leilei,CPO' 1.txt
101,oldboy,CEO
106,dandan,CSO # 插入两行,本属于第二行的内容会在新增内容的下方
107,leilei,CPO
102,zhangyao,CTO
103,Alex,COO
104,yy,CFO
105,feixue,CIO
sed 不同行多项增加 sed -e
[root@chenleilei ~]# sed -e '2i 123' -e '5i 456' sed.log
101,$oldboy,CEO
123
102,$zhangyao,CTO
103,$Alex,COO
104,$yy,CFO
456
105,$feixue,CIO
[root@chenleilei ~]# sed '2a nihaoya\nwohenhao' sed.log
101,$oldboy,CEO
102,$zhangyao,CTO
nihaoya
wohenhao
103,$Alex,COO
104,$yy,CFO
105,$feixue,CIO
复杂用法:
sed软件可以对单行或多行进行处理。如果在sed命令前面不指定地址范围,那么默认会匹配所有行。
用法:n1[,n2]{sed-commands}
地址用逗号分隔的,n1,n2可以用数字、正则表达式、或二者的组合表示。
例子:
10{sed-commands} 对第10行操作
10,20{sed-commands} 对10到20行操作,包括第10,20行
10,+20{sed-commands} 对10到30(10+20)行操作,包括第10,30行
1~2{sed-commands} 对1,3,5,7,……行操作
10,${sed-commands} 对10到最后一行($代表最后一行)操作,包括第10行
/oldboy/{sed-commands} 对匹配oldboy的行操作
/oldboy/,/Alex/{sed-commands} 对匹配oldboy的行到匹配Alex的行操作
/oldboy/,${sed-commands} 对匹配oldboy的行到最后一行操作
/oldboy/,10{sed-commands} 对匹配oldboy的行到第10行操作,注意:如果前10行没有匹配到oldboy,sed软件会显示10行以后的匹配oldboy的行,如果有。
1,/Alex/{sed-commands} 对第1行到匹配Alex的行操作
/oldboy/,+2{sed-commands} 对匹配oldboy的行到其后的2行操作
sed 删
[root@oldboy ~]# sed 'd' 1.txt
[root@oldboy ~]#
[root@oldboy ~]# sed '2d' 1.txt
101,oldboy,CEO
103,Alex,COO
104,yy,CFO
105,feixue,CIO
[root@oldboy ~]# sed '2,5d' 1.txt
101,oldboy,CEO
[root@oldboy ~]# sed '3,$d' 1.txt
101,oldboy,CEO
102,zhangyao,CTO
[root@oldboy ~]# sed '1~2d' 1.txt
102,zhangyao,CTO
104,yy,CFO
[root@oldboy ~]# sed '1,+2d' 1.txt
104,yy,CFO
105,feixue,CIO
[root@oldboy ~]# sed '/zhangyao/d' 1.txt
101,oldboy,CEO
103,Alex,COO
104,yy,CFO
105,feixue,CIO
[root@oldboy ~]# sed '/oldboy/,/Alex/d' 1.txt
104,yy,CFO
105,feixue,CIO
[root@oldboy ~]# sed '/oldboy/,3d' 1.txt
104,yy,CFO
105,feixue,CIO
【删】sed删除案例3:删除不连续的行
seq 10 |sed -e{2,4,8}d ##注意这里不能添加引号或者双引号,否则报错
删除连续的行
[root@chenleilei ~]# sed '2,4d' sed.log
101,$oldboy,CEO
105,$feixue,CIO
案例:打印文件内容但不包含oldboy的行
[root@oldboy ~]# sed '/oldboy/d' person.txt #→删除包含"oldboy"的行
102,zhangyao,CTO
103,Alex,COO
104,yy,CFO
105,feixue,CIO
sed 改
sed -c 替换指定行
sed -i 修改指定行
sed s: 单独使用→将每一行中第一处匹配的字符串进行替换 ==>sed命令
sed g: 每一行进行全部替换 ==>sed命令s的替换标志之一,非sed命令
[root@oldboy ~]# sed 's#zhangyao#oldboyedu#g' 1.txt
101,oldboy,CEO
102,oldboyedu,CTO
103,Alex,COO
104,yy,CFO
105,feixue,CIO
[root@oldboy ~]# cat person.txt
101,oldboy,CEO
102,zhangyao,CTO
103,Alex,COO
104,yy,CFO
105,feixue,CIO
[root@oldboy ~]# sed -i 's#zhangyao#BBB#g' 1.txt
[root@oldboy ~]# cat person.txt
101,oldboy,CEO
102,BBB,CTO
103,Alex,COO
104,yy,CFO
105,feixue,CIO
sed -c 替换2 3 行为 111
[root@leilei ~]# sed '2,3c 111' 1.txt
101,oldboy,CEO
111
104,yy,CFO
105,feixue,CIO
sed 查
sed -n 搜索匹配
[root@leilei ~]# sed -n '/^104/p' 1.txt
104,yy,CFO
[root@chenleilei ~]# sed -nr '/103|105/!p' sed.log
101,$oldboy,CEO
102,$zhangyao,CTO
104,$yy,CFO ### !除了103.105开头的行 都删除 然后打印
案例: sed 匹配出ip地址 单项编辑和多项编辑
sed 可以使用正则表达式
网卡信息:
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 10.0.0.20 netmask 255.255.255.0 broadcast 10.0.0.255
inet6 fe80::20c:29ff:feb5:ac18 prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:b5:ac:18 txqueuelen 1000 (Ethernet)
RX packets 2457 bytes 232692 (227.2 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 1717 bytes 195015 (190.4 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
#解析:
sed 可以通过匹配字符来查找内容,这里查找网卡,我们可以通过指定 ^inet 的行 然后通过 netmask为结尾匹配
这样即使不指定行也能通过这两个条件匹配到该行,然后通过 (.*) 引出 匹配的内容 \1 输出
#方法:
ifconfig eth0| sed -rn 's#^.*et (.*) netmask.*$#\1#gp'
sed 同时取出 ip 掩码 网关(通过sed 多项编辑匹配然后打印出)
[root@leilei ~]# ip a | sed -nr 's#^.*net (.*)\/24.*brd (.*) scope.*$#\1 \2#gp'
10.0.0.20 10.0.0.255
ifconfig eth0 网卡信息取出:
[root@leilei ~]# ifconfig eth0 | sed -nr 's#^.*net (.*) netmask (.*) bro.*cast (.*)#\1 \2 \3#gp'
10.0.0.20 255.255.255.0 10.0.0.255
[root@leilei ~]# ifconfig eth0 | sed -nr 's#^.*net (.*) netmask (.*) bro.*cast (.*)#\1 \2#gp'
10.0.0.20 255.255.255.0
[root@leilei ~]# ifconfig eth0 | sed -nr 's#^.*net (.*) netmask (.*) bro.*cast (.*)#\1#gp'
10.0.0.20
熟悉了这两种方法,在你取出其他想要的字符的时候会变得非常轻松