栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 运维 > Linux

linux文本处理-awk

Linux 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力
文本处理三剑客之 awk awk 工作原理和基本用法说明

awk:Aho, Weinberger, Kernighan,报告生成器,格式化文本输出,GNU/Linux发布的AWK目前由自由软件基金会(FSF)进行开发和维护,通常也称它为 GNU AWK

有多种版本:

    AWK:原先来源于 AT & T 实验室的的AWK
    NAWK:New awk,AT & T 实验室的AWK的升级版
    GAWK:即GNU AWK。所有的GNU/Linux发布版都自带GAWK,它与AWK和NAWK完全兼容

gawk:模式扫描和处理语言,可以实现下面功能

    文本处理
    输出格式化的文本报表
    执行算数运算
    执行字符串操作

格式:

awk [options]   'program'     var=value   file…
awk [options]   -f programfile    var=value  file…

说明:

program通常是被放在单引号中,并可以由三种部分组成

    BEGIN语句块
    模式匹配的通用语句块
    END语句块

常见选项:

    -F “分隔符”  指明输入时用到的字段分隔符
    -v  var=value 变量赋值

Program格式:

pattern{action statements;..}

pattern:决定动作语句何时触发及触发事件,比如:BEGIN,END
action statements:对数据进行处理,放在{}内指明,常见:print, printf

awk 工作过程


awk

第一步:执行BEGIN{action;… }语句块中的语句
第二步:从文件或标准输入(stdin)读取一行,然后执行pattern{ action;… }语句块,它逐行扫描文件,从第一行到最后一行重复这个过程,直到文件全部被读取完毕。
第三步:当读至输入流末尾时,执行END{action;…}语句块
BEGIN语句块在awk开始从输入流中读取行之前被执行,这是一个可选的语句块,比如变量初始化、打印输出表格的表头等语句通常可以写在BEGIN语句块中
END语句块在awk从输入流中读取完所有的行之后即被执行,比如打印所有行的分析结果这类信息汇总都是在END语句块中完成,它也是一个可选语句块
pattern语句块中的通用命令是最重要的部分,也是可选的。如果没有提供pattern语句块,则默认执行{ print },即打印每一个读取到的行,awk读取的每一行都会执行该语句块

分割符、域和记录

    
    
    文件的每一行称为记录record
    如果省略action,则默认执行 print ​$0 的操作

常用的action分类

    output statements:print,printf
    expressions:算术,比较表达式等
    Compound statements:组合语句
    Control statements:if, while等
    input statements

awk控制语句

    { statements;… } 组合语句
    if(condition) {statements;…} 
    if(condition) {statements;…} else {statements;…}
    while(conditon) {statments;…}
    do {statements;…} while(condition)
    for(expr1;expr2;expr3) {statements;…}
    break
    continue
    exit 
动作 print

格式:

print item1, item2, ...

说明:

    逗号分隔符
    输出item可以字符串,也可是数值;当前记录的字段、变量或awk的表达式
    如省略item,相当于print $0

范例:

[root@centos8 ~]#awk    '{print "hello,awk"}'
[root@centos8 ~]#awk -F: '{print "wang"}' /etc/passwd
[root@centos8 ~]#awk -F: '{print}' /etc/passwd
[root@centos8 ~]#awk -F: '{print 0}' /etc/passwd
[root@centos8 ~]#awk -F: '{print1,3}' /etc/passwd
[root@centos8 ~]#awk -F: '{print1"t"3}' /etc/passwd
[root@centos8 ~]#grep "^UUID" /etc/fstab |awk {'print2,3'}
/ xfs
/boot ext4
/data xfs
swap swap
[root@centos8 ~]#awk '{print1}' access_log |sort |uniq -c|sort -nr|head 
   4870 172.20.116.228
   3429 172.20.116.208
   2834 172.20.0.222
   2613 172.20.112.14
   2267 172.20.0.227
   2262 172.20.116.179
   2259 172.20.65.65
   1565 172.20.0.76
   1482 172.20.0.200
   1110 172.20.28.145

[root@centos8 ~]#df | awk -F"[[:space:]]+|%" '{print 5}'
Use
0
0
1
0
5
1
92
1
[root@centos8 ~]#df | grep "^/dev/sd" | awk -F"[[:space:]]+|%" '{print5}'
5
1
92

[root@centos8 ~]#df |  awk -F"[[:space:]]+|%" '/^/dev/sd/{print $5}'
5
1
92
awk变量

awk中的变量分为:内置和自定义变量

常见的内置变量

FS:输入字段分隔符,默认为空白字符,功能相当于 -F

范例:

awk -v FS=':'  '{print 1,FS,3}' /etc/passwd
awk -v FS=":" '{print 1FS3}' /etc/passwd
awk –F:   '{print 1,3,7}'   /etc/passwd    
S=:;awk -v FS=S '{print 1FS3}' /etc/passwd

OFS:输出字段分隔符,默认为空白字符

范例:

awk  -v FS=':'  -v OFS=':'  '{print 1,3,$7}'   /etc/passwd

RS:输入记录分隔符,指定输入时的换行符

范例:

awk -v RS=' ' ‘{print }’ /etc/passwd

ORS:输出记录分隔符,输出时用指定符号代替换行符

范例:

awk -v RS=' ' -v ORS='###'  '{print $0}' /etc/passwd

NF:字段数量

范例:

#引用变量时,变量前不需加[root@centos8 ~]#awk  -F:'{print NF}'     /etc/fstab  
[root@centos8 ~]#awk  -F:'{print(NF-1)}'  /etc/passwd
[root@centos8 ~]#ls /misc/cd/baseOS/Packages1/p'|sort |uniq -c
    529 ESTAB    
      9 LISTEN   
    128 SYN-RECV 
     95 TIME-WAIT
[root@centos8 ~]#ss -ant | awk 'NR!=1{state[1]++}END{for(i in state){print i,state[i]}}'
SYN-RECV 128
LISTEN 9
ESTAB 529
TIME-WAIT 95

[root@centos8 ~]#netstat -tan | awk '/^tcp/{state[NF]++}END{for(i in state){print i,state[i]}}'
LISTEN 9
SYN_RECV 126
ESTABLISHED 523
FIN_WAIT2 40

[root@centos8 ~]#awk '{ip[1]++}END{for(i in ip){print i,ip[i]}}' /var/log/httpd/access_log
172.20.0.200 1482
172.20.21.121 2
172.20.30.91 29
172.16.102.29 864
172.20.0.76 1565
172.20.9.9 15
172.20.1.125 463
172.20.61.11 2
172.20.73.73 198

[root@centos8 ~]#awk '{ip[1]++}END{for(i in ip){print ip[i],i}}' access_log  |sort -nr| head -3
4870 172.20.116.228
3429 172.20.116.208
2834 172.20.0.222
[root@centos8 ~]#awk '{ip[$1]++}END{for(i in ip){print i,ip[i]}}' access_log |sort -k2 -nr|head -3
172.20.116.228 4870
172.20.116.208 3429
172.20.0.222 2834

范例:多维数组

[root@centos8 ~]#awk 'BEGIN{
> array[1][1]=11
> array[1][2]=12
> array[1][3]=13
> array[2][1]=21
> array[2][2]=22
> array[2][3]=23
> for (i in array)
>     for (j in array[i])
>         print array[i][j]
> }'
11
12
13
21
22
23
awk函数

awk 的函数分为内置和自定义函数

常见内置函数

数值处理:
rand():返回0和1之间一个随机数

srand():配合rand() 函数,生成随机数的种子

int():返回整数

范例:

[root@centos8 ~]#awk 'BEGIN{srand();print rand()}'
0.790437
[root@centos8 ~]#awk 'BEGIN{srand();print rand()}'
0.283736
[root@centos8 ~]#awk 'BEGIN{srand();print rand()}'
0.948082
[root@centos8 ~]#awk 'BEGIN{srand();print rand()}'
0.371798

[root@centos8 ~]#awk  'BEGIN{srand(); for (i=1;i<=10;i++)print int(rand()*100) }' 
35
17
35
95
19
15
70
54
46
93

字符串处理:

length([s]):返回指定字符串的长度

sub(r,s,[t]):对t字符串搜索r表示模式匹配的内容,并将第一个匹配内容替换为s

范例:

[root@centos8 ~]#echo "2008:08:08 08:08:08" | awk 'sub(/:/,"-",1)'
2008-08:08 08:08:08

[root@centos8 ~]#echo "2008:08:08 08:08:08" | awk '{sub(/:/,"-",1);print $0}'
2008-08:08 08:08:08

gsub(r,s,[t]):对t字符串进行搜索r表示的模式匹配的内容,并全部替换为s所表示的内容

范例:

[root@centos8 ~]#echo "2008:08:08 08:08:08" | awk 'gsub(/:/,"-",0)'
2008-08-08 08-08-08

[root@centos8 ~]#echo "2008:08:08 08:08:08" | awk '{gsub(/:/,"-",0);print $0}'
2008-08-08 08-08-08

split(s,array,[r]):以r为分隔符,切割字符串s,并将切割后的结果保存至array所表示的数组中,第一个索引值为1,第二个索引值为2,…

范例:

[root@centos8 ~]#netstat -tn | awk '/^tcp/{split($5,ip,":");count[ip[1]]++}END{for(i in count){print i,count[i]}}'
10.0.0.1 1
10.0.0.6 1
10.0.0.7 673

system 函数:可以awk中调用shell命令
空格是awk中的字符串连接符,如果system中需要使用awk中的变量可以使用空格分隔,或者说除了awk的变量外其他一律用""引用起来

awk 'BEGIN{system("hostname")}' 
awk 'BEGIN{score=100; system("echo  your score is " score) }'

[root@centos8 ~]#netstat -tn | awk '/^tcp/{split($5,ip,":");count[ip[1]]++}END{for(i in count){if(count[i]>=10){system("iptables -A INPUT -s "i" -j REJECT")}}}'
自定义函数

自定义函数格式:

function name ( parameter, parameter,  ... ) {
   statements
   return expression
}

范例:

[root@centos8 ~]#cat func.awk
function max(x,y) {
    x>y?var=x:var=y
    return var
}
BEGIN{print max(a,b)}
[root@centos8 ~]#awk  -v a=30 -v b=20 -f func.awk
30
awk脚本

将awk程序写成脚本,直接调用或执行

范例:

[root@centos8 ~]#cat passwd.awk 
{if(3>=1000)print1,$3}
[root@centos8 ~]#awk -F: -f passwd.awk /etc/passwd
nobody 65534
wang 1000
mage 1001

范例:

[root@centos8 ~]#cat test.awk
#!/bin/awk -f
#this is a awk script
{if(3>=1000)print1,$3}
[root@centos8 ~]#chmod +x test.awk
[root@centos8 ~]#./test.awk -F: /etc/passwd
nobody 65534
wang 1000
mage 1001

向awk脚本传递参数

格式:

awkfile  var=value var2=value2... Inputfile

注意:在BEGIN过程中不可用。直到首行输入完成以后,变量才可用。可以通过-v 参数,让awk在执行BEGIN之前得到变量的值。命令行中每一个指定的变量都需要一个-v参数

范例:

[root@centos8 ~]#cat test2.awk 
#!/bin/awk -f
{if(3 >=min &&3<=max)print 1,3} 
[root@centos8 ~]#chmod +x test2.awk
[root@centos8 ~]#./test2.awk  -F: min=100 max=200 /etc/passwd
systemd-resolve 193
rtkit 172
pulse 171
qemu 107
usbmuxd 113
abrt 173

练习

1、文件host_list.log 如下格式,请提取”.magedu.com”前面的主机名部分并写入到回到该文件中

1 www.magedu.com
2 blog.magedu.com
3 study.magedu.com
4 linux.magedu.com
5 python.magedu.com
......
999 study.magedu.com

参考答案:

[root@centos8 ~]#cat host_list.log
1 www.magedu.com
2 blog.magedu.com
3 study.magedu.com
4 linux.magedu.com
5 python.magedu.com
[root@centos8 ~]#awk -F"[ .]"  '{print 2}' host_list.log
www
blog
study
linux
python
[root@centos8 ~]#awk -F"[ .]"  '{print2}' host_list.log >> host_list.log 
[root@centos8 ~]#cat host_list.log
1 www.magedu.com
2 blog.magedu.com
3 study.magedu.com
4 linux.magedu.com
5 python.magedu.com
www
blog
study
linux
python

2、统计/etc/fstab文件中每个文件系统类型出现的次数
3、统计/etc/fstab文件中每个单词出现的次数
4、提取出字符串Yd$C@M05MB%9&Bdh7dq+YVixp3vpw中的所有数字
5、有一文件记录了1-100000之间随机的整数共5000个,存储的格式100,50,35,89…请取出其中最大和最小的整数
6、解决DOS攻击生产案例:根据web日志或者或者网络连接数,监控当某个IP并发连接数或者短时内PV达到100,即调用防火墙命令封掉对应的IP,监控频率每隔5分钟。防火墙命令为:iptables -A INPUT -s IP -j REJECT

7、将以下文件内容中FQDN取出并根据其进行计数从高到低排序

http://mail.magedu.com/index.html
http://www.magedu.com/test.html
http://study.magedu.com/index.html
http://blog.magedu.com/index.html
http://www.magedu.com/images/logo.jpg
http://blog.magedu.com/20080102.html
http://www.magedu.com/images/magedu.jpg

参考答案:

[root@centos8 ~]#awk -F"/" '{url[$3]++}END{for(i in url){print url[i],i}}' url.log |sort -nr
3 www.magedu.com
2 blog.magedu.com
1 study.magedu.com
1 mail.magedu.com

8、将以下文本以inode为标记,对inode相同的counts进行累加,并且统计出同一inode中,beginnumber的最小值和endnumber的最大值

inode|beginnumber|endnumber|counts|
106|3363120000|3363129999|10000|
106|3368560000|3368579999|20000|
310|3337000000|3337000100|101|
310|3342950000|3342959999|10000|
310|3362120960|3362120961|2|
311|3313460102|3313469999|9898|
311|3313470000|3313499999|30000|
311|3362120962|3362120963|2|

输出的结果格式为:

310|3337000000|3362120961|10103|
311|3313460102|3362120963|39900|
106|3363120000|3368579999|30000|
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/10366.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号