技术流ken

运维拯救世界

1904课堂记录:shell编程5-sed和awk

文本处理三剑客

grep

sed

awk

 

sed详解

 

使用格式:

 

sed 选项 CMD 文件名

 

sed -n ‘3p’ filename

 

 

-n选项

p 打印

上述命令表示的含义:

打印filename中第三行的内容

 

option[选项] 解释说明(带*的为重点)
-n (no) 取消默认的sed软件的输出,常与sed命令的p连用。*
-e (entry) 一行命令语句可以执行多条sed命令   *
-r (ruguler) 使用扩展正则表达式,默认情况sed只识别基本正则表达式  *
-i (inside) 直接修改文件内容,而不是输出到终端

 

 

 

sed -commands[sed命令] 解释说明(带*的为重点)
a (append) 追加,在指定行后添加一行或多行文本 *                                                      
c (change) 取代指定的行
d (delete) 删除指定的行  *  
i (insert) 插入,在指定行前添加一行或多行文本 *
p (print) 打印模式空间内容,通常p会与选项-n一起使用*
特殊符号 解释说明(带*的为重点)
对指定行以外的所有行应用命令*    

 

sed增删改查

 

1.增 i a

例子1:在test文件第三行前插入名字

[root@ken1 ~]# sed ‘3i ken’ test
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
ken
daemon:x:2:2:daemon:/sbin:/sbin/nologin

 

例子2:在末尾最后一行前插入内容

[root@ken1 ~]# sed ‘$i ken’ test

 

例子3:在首行插入内容

[root@ken1 ~]# sed ‘1i ken’ test

 

2.a

例子4:在3行追加内容

[root@ken1 ~]# sed ‘3a ken’ test

 

例子5:在末行追加

[root@ken1 ~]# sed ‘$a ken’ test

 

3.d

 

例子1:删除第一行的内容

[root@ken1 ~]# sed ‘1d’ test

 

例子2:删除末尾的行

[root@ken1 ~]# sed ‘$d’ test

 

例子3:删除1到5行的内容

[root@ken1 ~]# sed ‘1,5d’ test

 

例子4:删除1,4,5行的内容

[root@ken1 ~]# sed -e ‘1d’ -e ‘4,5d’ test

 

4. c

例子1:把第一行内容替换为名字

[root@ken1 ~]# sed ‘1c ken’ test

 

例子2:插入多行

[root@ken1 ~]# sed ‘1c 1\n2\n3’ test

 

 

5.p

例子1:查看第一行内容

[root@ken1 ~]# sed -n ‘1p’ test   #一般p要和-n连用
root:x:0:0:root:/root:/bin/bash

 

例子2:打印1到4行的内容

[root@ken1 ~]# sed -n ‘1,4p’ test

 

例子3:打印最后一行

[root@ken1 ~]# sed -n ‘$p’ test

 

例子4:打印出来包含root的行

[root@ken1 ~]# sed -n ‘/root/p’ test

 

例子5:打印出来以root开头的行

[root@ken1 ~]# sed -n ‘/^root/p’ test

 

 

6.

1.删除文本第一行的内容

[root@ken1 ~]# sed -i ‘1d’ test

 

 

注意:在使用sed的时候一定要事先备份要操作的文件,

需要清除的知道敲的命令会产生什么样的后果再去执行!

 

 

7.取反

例子1:不打印3到5行的内容

[root@ken1 ~]# sed -n ‘3,5!p’ test

 

8.替换

 

例子1:替换文中所有的root为ken

[root@ken1 ~]# sed ‘s/root/ken/g’ test

 

例子2:实际所有的root为ken

[root@ken1 ~]# sed -i ‘s/root/ken/g’ test

 

例子3:仅替换一ken开头的行的ken为root

[root@ken1 ~]# sed ‘/^ken/{s/ken/root/g}’ test

 

例子4:更改selinux状态

 

方法一:

[root@ken1 ~]# sed ‘s/SELINUX=disabled/SELINUX=enforcing/’ /etc/sysconfig/selinux

 

方法二:

[root@ken1 ~]# sed -r ‘s/(SELINUX=)disabled/\1enforcing/’ /etc/sysconfig/selinux

 

 

总结sed常用用法:

1.查找指定的字符串

方法1:set '/root/p' /etc/passwd

 

2.在指定的位置做增删

# sed ‘/root/a i am ken’ a.txt

 

3.按行替换

例子:将5到9行的内容替换为 i am ken

# sed ‘5,9c i am ken’ a.txt

 

4.按照字符替换

例子:将/etc/selinux/config中的SELINUX=enforcing改成 disabled

写法1:# sed -i ‘s/SELINUX=disabled/SELINUX=enforcing/g’ config

写法2:# sed -r -i ‘s/(SELINUX=)disabled/\1enforcing/g’ config

 

5.查找指定的内容再做替换

例子:将以r开头的行中的oo替换为qq

# sed ‘/^r/{s/oo/qq/g}’ passwd

 

6.取反操作

显示非1-3行

# sed -n ‘1,3!p’ passwd

 

7.多点编辑-e

例子1:去除文件中的注释行和空白行

方法一:

[root@ken1 ~]# sed -e ‘/^#/d’ -e ‘/^$/d’ test

 

方法二:

[root@ken1 ~]# grep -v -e “^#” -e “^$” test.bak > test

 

方法三:

[root@ken1 ~]# grep -E -v ‘(^$)|(^#)’ test.bak

 

awk用法详解

 

awk格式

awk 选项 ‘pattern {action}’ filename

pattern表示匹配内容

action 匹配到内容之后想要执行的操作

选项:

-F  指定分隔符 #可以直接写基础正则和扩展正则

 

输出字段的表示方式

 

$1 $2 … $n 输出一个指定的字段

$NF 输出最后一个字段

$0 输出整条记录

 

例子1:输出第一行内容

[root@ken1 ~]# awk ‘NR==1{print $0}’ test

ken:x:0:0:ken:/ken:/bin/bash

NR==1 表示我要匹配第一行

{print $0} 表示打印出来整行内容

 

只有满足匹配条件的时候,才会执行花括号里面的动作!

 

例子1:打印行号

[root@ken1 ~]# awk ‘{print NR,$0}’ test

 

例子2:只显示用户名

[root@ken1 ~]# awk -F “:” ‘{print $1}’ test

 

例子3;只显示shell类型

方法一:

[root@ken1 ~]# awk -F “:” ‘{print $7}’ test

 

方法二:

[root@ken1 ~]# awk -F “:” ‘{print $NF}’ test

 

例子4:同时显示用户名和shell类型

[root@ken1 ~]# awk -F “:” ‘{print $1,$NF}’ test

 

例子5:打印出来包含root的行

[root@ken1 ~]# awk ‘/ken/{print $0}’ test

 

例子6:打印出来以ken开头的行

[root@ken1 ~]# awk ‘/^ken/{print $0}’ test

 

或者:

[root@ken1 ~]# awk ‘/^ken/’ test
ken:x:0:0:ken:/ken:/bin/bash

 

例子7:打印出来字段大于五个的行的第三个字段

[root@ken1 ~]# awk -F “:” ‘NF>=5{print $3}’ test

 

awk正则

 

[root@ken1 ~]# awk ‘$0~/ken/’ test
ken:x:0:0:ken:/ken:/bin/bash
operator:x:11:0:operator:/ken:/sbin/nologin

[root@ken1 ~]# awk ‘$0~/^ken/’ test
ken:x:0:0:ken:/ken:/bin/bash

 

$0 表示一行内容

~   表示接下来要正则匹配

//  进行内容匹配

 

$0~/ken/’

 

表示在整行内容中匹配包含ken的的行

 

[root@ken1 ~]# awk -F “:” ‘$5~/k/’ test
ken:x:0:0:ken:/ken:/bin/bash

 

表示含义:第五个字段包含k的行

 

取出网卡IP地址:

[root@ken1 ~]# ip a | awk “/global/” | awk -F “( +)|(/)” ‘{print $3}’
192.168.163.5

作业:至少没人想到五种办法!

 

 

BEGIN 和END模块

 

  • BEGIN模块再awk读取文件之前就执行,一般用来定义我们的内置变量(预定义变量,eg:FS,RS)
  • 需要注意的是BEGIN模式后面要接跟一个action操作块,包含在大括号内。awk必须在输入文件进行任何处理前先执行BEGIN里的动作(action)。我们可以不要任何输入文件,就可以对BEGIN模块进行测试,因为awk需要先执行完BEGIN模式,才对输入文件做处理。BEGIN模式常常被用来修改内置变量ORS,RS,FS,OFS等值。

BEGIN模块

例子1:首行输出一些字段

[root@ken1 ~]# awk -F “:” ‘BEGIN{print “username”}{print $1}’ test

 

例子2:使用BEGIN指定分隔符

[root@ken1 ~]# ip a | awk “/global/” | awk ‘BEGIN {FS=”( +)|(/)”}{print $3}’

 

END模块

 

例子1:在最后一行打印一些字段

[root@ken1 ~]# awk -F “:” ‘{print $1}END{print “end of file”}’ test

 

例子2:统计文本中root出现的行的数量

[root@ken1 ~]# awk ‘BEGIN{num=0}/ken/{num++}END{print num}’ test

 

首先定义了num初始值为0,然后进行root匹配,如果匹配到root的行就会让num加1,等读取完所有的文本之后,再去打印num的数量。

 

或者

[root@ken1 ~]# awk ‘/ken/{num++}END{print num}’ test

 

 

awk数组

 

如下的文件:统计出来域名出现的次数,并按照从大到小进行排序

http://www.qq.com/ken
http://www.qq.com/ken
http://www.qq.com/ken
http://www.qq.com/ken
http://www.qq.com/ken
http://www.qq.com/ken
http://www.qq.com/ken
http://www.sina.com/ken
http://www.sina.com/ken
http://www.sina.com/ken
http://www.sina.com/ken
http://www.sina.com/ken
http://www.sina.com/ken
http://www.sina.com/ken
http://www.sina.com/ken
http://www.sina.com/ken
http://www.sina.com/ken
http://www.sina.com/ken
http://www.sina.com/ken
http://www.sina.com/ken
http://www.taobao.com/ken
http://www.taobao.com/ken
http://www.taobao.com/ken
http://www.taobao.com/ken
http://www.taobao.com/ken
http://www.taobao.com/ken
http://www.taobao.com/ken
http://www.taobao.com/ken
http://www.taobao.com/ken
http://www.taobao.com/ken
http://www.taobao.com/ken
http://www.taobao.com/ken
http://www.taobao.com/ken
http://www.taobao.com/ken
http://www.taobao.com/ken
http://www.taobao.com/ken
http://www.taobao.com/ken
http://www.taobao.com/ken
http://www.taobao.com/ken
http://www.taobao.com/ken
http://www.taobao.com/ken
http://www.taobao.com/ken
http://www.taobao.com/ken
http://www.taobao.com/ken
http://www.taobao.com/ken

 

 

方法一:

[root@ken1 ~]# cat test | cut -d “/” -f 3 | sort | uniq -c | sort -rn
25 www.taobao.com
13 www.sina.com
7 www.qq.com

 

方法二:

[root@ken1 ~]# awk -F “/+” ‘{ken[$2]++}END{for (i in ken) print ken[i],i}’ test | sort -rn
25 www.taobao.com
13 www.sina.com
7 www.qq.com

 

 

例子2:取出访问网站前10名的IP地址

方法一:

[root@ken245 ~]# cat /var/log/nginx/access.log | cut -d ” ” -f 1 | sort | uniq -c |sort -rn | head
1462 124.200.101.50
825 43.252.231.204
106 183.17.230.63
48 210.22.98.114
37 61.158.146.81
34 110.6.132.11
27 23.100.232.233
20 61.129.8.179
20 101.227.139.161
17 61.151.178.197

 

方法二:

[root@ken245 ~]# awk -F ” ” ‘{ken[$1]++}END{for (i in ken) print ken[i],i}’ /var/log/nginx/access.log | sort -rn | head
1468 124.200.101.50
825 43.252.231.204
106 183.17.230.63
48 210.22.98.114
37 61.158.146.81
34 110.6.132.11
27 23.100.232.233
20 61.129.8.179
20 101.227.139.161
17 61.151.178.197

发表评论

电子邮件地址不会被公开。