sed

  1. sed语法格式

sed [选项] [sed指令] [输入文件]

创建测试文件

cat>person.txt<<EOF
101,oldboy,CEO
102,zhangyao,CTO
103,Alex,COO
104,yy,CFO
105,feixue,CIO
EOF

EOF ==>end of file

查询单行文本

p sed指定,打印模式空间内容 -n sed选项,取消默认输出

[root@www ~]# sed '1p' person.txt 
101,oldboy,CEO
101,oldboy,CEO
102,zhangyao,CTO
103,Alex,COO
104,yy,CFO
105,feixue,CIO
[root@www ~]# sed -n '1p' person.txt 
101,oldboy,CEO
[root@www ~]# sed -n '3p' person.txt 
103,Alex,COO

查询连续多行文本

指定p前面没有地址范围,那么默认匹配所有行

2,4 显示第2行到第4行的内容,包含第2行和第4行

[root@www ~]# sed -n '2,4p' person.txt 
102,zhangyao,CTO
103,Alex,COO
104,yy,CFO

正则地址范围-模糊,容易找多了 #显示出文件中包含oldboy的行到包含104的行。。

[root@www oldboy]# #sed -n '/oldboy/p' person.txt  ===== grep 'oldboy'
[root@www oldboy]# sed -n '/oldboy/p' person.txt 
101,oldboy,CEO
[root@www oldboy]# sed -n '/oldboy/,/^104/p' person.txt 
101,oldboy,CEO
102,zhangyao,CTO
103,Alex,COO
104,yy,CFO

过滤多个字符串 -r sed选项,支持扩展正则表达式(|、()) 因为默认情况,sed只支持基本正则表达式。

[root@www ~]# sed -n '/oldboy/p' person.txt 
101,oldboy,CEO
[root@www ~]# egrep 'oldboy|yy' person.txt   ==egrep ==grep -E
101,oldboy,CEO
104,yy,CFO
[root@www ~]# sed -rn '/oldboy|yy/p' person.txt 
101,oldboy,CEO
104,yy,CFO

sed里面的正则字符左右必须有“/”。/oldboy/

小结: 1.查询某一行 查询某一个范围 1p 2,4p 2.通过正则表达式查询范围 sed -n '/oldboy/,/^104/p' person.txt 3.sed命令通过正则表达式进行过滤 ==== egrep

查询指定多行,使用分号

[root@www ~]# sed -n '2p;4p' person.txt 
102,zhangyao,CTO
104,yy,CFO
[root@www ~]# sed -n '2p;4p;10p;30p' person.txt 

增加单行文本

a 追加append,在指定行后添加一行或多行文本 i 插入insert,在指定行前添加一行或多行文本

[root@www ~]# sed '2a 106,xiaoyu,CXO' person.txt 
101,oldboy,CEO
102,zhangyao,CTO
106,xiaoyu,CXO
103,Alex,COO
104,yy,CFO
105,feixue,CIO
[root@www ~]# sed '2i 106,xiaoyu,CXO' person.txt 
101,oldboy,CEO
106,xiaoyu,CXO
102,zhangyao,CTO
103,Alex,COO
104,yy,CFO
105,feixue,CIO

增加多行文本 \n 表示换行符

[root@www ~]# sed '2a 106,xiaoyu,CXO\n107\n108\n109' person.txt 
101,oldboy,CEO
102,zhangyao,CTO
106,xiaoyu,CXO
107
108
109
103,Alex,COO
104,yy,CFO
105,feixue,CIO
cat >>person.txt<<EOF 
new,new,new
old,old,old
EOF

删除文件内容 d sed指令,删除文本内容 $ 代表文件的最后一行

[root@www ~]# sed '2d' person.txt   # 删除单行
101,oldboy,CEO
103,Alex,COO
104,yy,CFO
105,feixue,CIO
[root@www ~]# sed '2,5d' person.txt # 删除多行
101,oldboy,CEO
[root@www ~]# sed '2,$d' person.txt 
101,oldboy,CEO

企业案例:不显示文件中的空行

[root@www oldboy]# cat person.txt 
101,oldboy,CEO

102,zhangyao,CTO
103,Alex,COO

104,yy,CFO

105,feixue,CIO


[root@www oldboy]# cat -A person.txt
101,oldboy,CEO$
$
102,zhangyao,CTO$
103,Alex,COO$
$
104,yy,CFO$
$
105,feixue,CIO$

grep -v  '^$' person.txt 
sed '/^$/d' person.txt 
sed -n '/^$/!p' person.txt 
awk '!/^$/' person.txt 

sed '$d' person.txt 
sed '$!d' person.txt 

文本替换

s 单独使用→将每一行中第一处匹配的字符串进行替换 g 每一行进行全部替换→sed指令s的替换标志之一(全局替换)

[root@www ~]# sed 's#o#A#' person.txt 
101,Aldboy,CEO
102,zhangyaA,CTO
103,Alex,COO
104,yy,CFO
105,feixue,CIO
[root@www ~]# sed 's#o#A#g' person.txt 
101,AldbAy,CEO
102,zhangyaA,CTO
103,Alex,COO
104,yy,CFO
105,feixue,CIO

-i自动备份功能

[root@www ~]# sed -i.bak 's#o#A#g' person.txt 
[root@www ~]# cat person.txt
101,AldbAy,CEO
102,zhangyaA,CTO
103,Alex,COO
104,yy,CFO
105,feixue,CIO
[root@www ~]# cat person.txt.bak 
101,oldboy,CEO
102,zhangyao,CTO
103,Alex,COO
104,yy,CFO
105,feixue,CIO

变量替换

注意单引号、双引号的区别 单引号:所见即所得

双引号:与单引号类似 特殊符号会被解析 $ $() ! 以及反引号

[root@www oldboy]# x=oldboy
[root@www oldboy]# y=oldgirl

[root@www oldboy]# sed 's#$x#$y#g' person.txt 
101,oldboy,CEO

102,zhangyao,CTO
103,Alex,COO

104,yy,CFO

105,feixue,CIO

[root@www oldboy]# sed "s#$x#$y#g" person.txt 
101,oldgirl,CEO

102,zhangyao,CTO
103,Alex,COO

104,yy,CFO

105,feixue,CIO

反向引用

() 扩展正则表达式 在sed中作用,能够记忆它包含的一段正则表达式,并可以通过\1 \2 \3 ... \9 调取出来

sed -r '()'

企业案例:系统开机启动项优化

除了下面5个服务以外都关闭:crond sshd network sysstat rsyslog

chkconfig --list|grep 3:on|sed -r 's#(.*).*0.*#\1#'|egrep -v 'crond|sshd|network|sysstat|rsyslog'|sed -r 's#(.*)#chkconfig \1 off#'|bash


awk

基本的awk执行过程:

awk  参数  '模式{动作}'  文件 
awk  参数  '条件(找谁){干啥}'  文件 

[root@www ~]# awk -F ":"  'NR==2{print $1,$2}' /etc/passwd

通过正则表达式作为模式

mkdir -p /server/files/
cat >>/server/files/reg.txt<<EOF
Zhang Dandan    41117397   :250:100:175
Zhang Xiaoyu    390320151  :155:90:201
Meng  Feixue    80042789   :250:60:50
Wu    Waiwai    70271111   :250:80:75
Liu   Bingbing  41117483   :250:100:175
Wang  Xiaoai    3515064655 :50:95:135
Zi    Gege      1986787350 :250:168:200
Li    Youjiu    918391635  :175:75:300
Lao   Nanhai    918391635  :250:100:175
EOF

显示Xiaoyu的姓氏和ID号码

[root@www files]# awk '$2~/Xiaoyu/{print $1,$2,$3}' reg.txt 
Zhang Xiaoyu 390320151

显示所有以41开头的ID号码的人的全名和ID号码

[root@www files]# awk '$3~/^41/'  reg.txt 
Zhang Dandan    41117397   :250:100:175
Liu   Bingbing  41117483   :250:100:175
[root@www files]# awk '$3~/^41/{print $1,$2,$3}'  reg.txt 
Zhang Dandan 41117397
Liu Bingbing 41117483

显示所有ID号码最后一位数字是1或5的人的全名

[root@www files]# awk '$3~/[15]$/' reg.txt 
Zhang Xiaoyu    390320151  :155:90:201
Wu    Waiwai    70271111   :250:80:75
Wang  Xiaoai    3515064655 :50:95:135
Li    Youjiu    918391635  :175:75:300
Lao   Nanhai    918391635  :250:100:175

[root@www files]# awk '$3~/[15]$/{print $1,$2}' reg.txt 
Zhang Xiaoyu
Wu Waiwai
Wang Xiaoai
Li Youjiu
Lao Nanhai

显示Xiaoyu的捐款.每个值时都有以$开头.如$520$200$135 gsub(/目标/,"替换为什么",第几列) gsub(/目标/,"替换为什么") == gsub(/目标/,"替换为什么",$0)

[root@www files]# awk '$2~/Xiaoyu/' reg.txt 
Zhang Xiaoyu    390320151  :155:90:201
[root@www files]# awk '$2~/Xiaoyu/{gsub(/:/,"$");print}' reg.txt 
Zhang Xiaoyu    390320151  $155$90$201

特殊模式BEGIN和END BEGIN{} BEGIN里面的内容,会在awk读取文件内容之前运行。 一般用于测试,计算。

END{} END{}里面的内容,会在awk读取完文件的最后一行之后运行。 用来显示最终结果。 先计算,END显示结果。

统计/etc/services文件里面的空行数量

i=i+1 统计

[root@www files]# awk '/^$/{i=i+1}END{print i}' /etc/services 
16

先计算END{显示最终结果}

统计出现多少次 计数 i=i+1 == i++

awk数组-统计与计算

处理以下文件内容,将域名取出并根据域名进行计数排序处理:(百度和sohu面试题)

http://www.etiantian.org/index.html
http://www.etiantian.org/1.html
http://post.etiantian.org/index.html
http://mp3.etiantian.org/index.html
http://www.etiantian.org/3.html
http://post.etiantian.org/2.html
[root@www files]# awk 'BEGIN{h[110]="lee";h[114]="XO";print h[110],h[114]}'
lee XO

统计出现多少次 计数 i=i+1 == i++ h[$2]=h[$2]+1 == h[$2]++

[root@www files]# cat url.txt
http://www.etiantian.org/index.html
http://www.etiantian.org/1.html
http://post.etiantian.org/index.html
http://mp3.etiantian.org/index.html
http://www.etiantian.org/3.html
http://post.etiantian.org/2.html

[root@www files]# awk -F "[/.]+" '{print $2}' url.txt 
www
www
post
mp3
www
post
[root@www files]# awk -F "[/.]+" '{h[$2]=h[$2]+1;print h["www"]}' url.txt 
1
2
2
2
3
3

[root@www files]# awk -F "[/.]+" '{h[$2]=h[$2]+1}END{print h["www"],h["post"],h["mp3"]}' url.txt 
3 2 1
[root@www files]# awk -F "[/.]+" '{h[$2]=h[$2]+1}END{for(pol in h) print pol,h[pol]  }' url.txt 
www 3
mp3 1
post 2

awk总结: 1.awk数组进行统计 i=i+1 == i++ 统计次数 计数 i=i+$n == i+=$n 累计相加 累加 2.awk执行过程 3.awk通过正则作为模式 4.BEGIN和END特殊模式