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 熟悉了这两种方法,在你取出其他想要的字符的时候会变得非常轻松