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命令的执行流程图

Linux三剑客 sed_Linux

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 

熟悉了这两种方法,在你取出其他想要的字符的时候会变得非常轻松

Linux三剑客 sed_Linux_02