awk模式之正则及常用的字符串函数

版权声明:©来自CSDN博客作者"李在奋斗"的原创作品,如需转载,请注明出处 https://blog.csdn.net/qq_31725371/article/details/83870686

awk模式之正则

1. 格式化输出print和printf

// 和C语言风格一致,-表示左对齐,默认是右对齐;%s字符型,%d十进制数值型,%f浮点型
[root@mysql-master ~]# awk -F":" '{print "username: "$1 "\tuid: "$3}' /tmp/file1 
username: root	uid: 0
username: bin	uid: 1
username: daemon	uid: 2
[root@mysql-master ~]# 
[root@mysql-master ~]# awk -F":" '{printf "%-15s %-5s\n",$1,$3}' /tmp/file1 
root            0    
bin             1    
daemon          2    
[root@mysql-master ~]#

2. 正则表达式

[root@mysql-master ~]# awk '/^root/' /tmp/file1 
root:x:0:0:root:/root:/bin/bash
[root@mysql-master ~]# awk '$0 ~ /^root/' /tmp/file1   # 与上面等价,~表示匹配
root:x:0:0:root:/root:/bin/bash
[root@mysql-master ~]# 

[root@mysql-master ~]# awk '!/^root/' /tmp/file1 
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
[root@mysql-master ~]# awk '$0 !~ /^root/' /tmp/file1   # 与上面等价,!~表示不匹配
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
[root@mysql-master ~]# awk '$NF!~/bash/' /tmp/file1     #筛选shell不是bash的用户
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
[root@mysql-master ~]#

3. 关系运算符及其他运算符

运算符 说明 运算符 说明
丨丨 , && 逻辑或 =,+=,-+,*=,/=,%= 赋值,运算
按位与 <=,>=,<,> 小于等于,大于等于,小于,大于
^ 按位异或 <<,>> 按位左移,按位右移
& 按位与 +,-,*,/,% 加减乘除取模
==,!= 等于,不等于 !,~ 逻辑非,按位取反或补码
其他运算符 说明
$ 字段引用
空格 字符串连接符
?: C语言中条件表达式
in 数组中是否存在某键值
例:
[root@mysql-master ~]# awk 'BEGIN{a="root";print a=="root"?"ok":"err";}'
ok
[root@mysql-master ~]# awk 'BEGIN{a="b";arr[0]="b";arr["b"]="c";print (a in arr);}'
1
[root@mysql-master ~]# awk 'BEGIN{a="b";arr[0]="b";arr[1]="c";print (a in arr);}'
0
[root@mysql-master ~]#
例1:使用in按索引遍历(也支持C语言风格,不推荐)
[root@mysql-master ~]# awk -F":" '{user[j++]=$1} END{for(i in user){print i, user[i]} }' /tmp/file1 
0 root
1 bin
2 daemon
[root@mysql-master ~]# awk -F":" '{user[j++]=$1} END{for(i=0;i<j;i++){print i, user[i]} }' /tmp/file1 
0 root
1 bin
2 daemon
[root@mysql-master ~]#
例2:统计用户shell的类型
//(行处理过程就是数组赋值的过程)
[root@mysql-master ~]# awk -F":" '{shells[$NF]++} END{for(i in shells){print i,shells[i]}}' /etc/passwd
/bin/sync 1
/bin/bash 4
/sbin/nologin 17
/sbin/halt 1
/sbin/shutdown 1
[root@mysql-master ~]#
例3:统计网站访问状态(想统计什么就把什么作为索引,在遍历索引即可)
[root@mysql-master /soft/scripts]# ss -an |grep 80 |awk '{status[$2]++} END{for(i in status){print i,status[i]}}'
LISTEN 31
ESTAB 84
[root@mysql-master /soft/scripts]# sh tcp_status.sh 
ESTAB: 84
LISTEN: 31
[root@mysql-master /soft/scripts]#
例4:对访问ip的top10进行排序
ss -ant |grep ':80' |awk -F":" '!/LISTEN/{ips[$NF-1]++} END{for(i in ips){print i,ips[i]}}'|sort -k2 -rn|head -10

例5:统计Nginx某一天的PV量<统计日志>
[root@web-node2 ~]# grep '22/Oct/2018' /var/log/nginx/access.log|wc -l
55              # Nginx某一天的PV量
[root@web-node2 ~]# grep '22/Oct/2018' | awk '{ips[$1]++} END{for(i in ips){print i"访问次数: "ips[i]}}' /var/log/nginx/access.log-20181107 
192.168.1.100访问次数:36
192.168.1.10访问次数:1
[root@web-node2 ~]# awk '/22\/Oct\/2018/{ips[$1]++} END{for(i in ips){print i"访问次数: "ips[i]}}' /var/log/nginx/access.log-20181107 
192.168.1.100访问次数:36
192.168.1.10访问次数:1
[root@web-node2 ~]# awk '/22\/Oct\/2018/{ips[$1]++} END{for(i in ips){print i"访问次数: "ips[i]}}' /var/log/nginx/access.log-20181107 |sort -k2 -rn -t":"|head -10
192.168.1.100访问次数: 36
192.168.1.10访问次数: 1
## 还是先用grep方便点,不用转义的

awk的内置字符串函数

格式 描述
gsub( Ere, Repl, [ In ] ) 除了正则表达式所有具体值被替代这点,它和 sub 函数完全一样地执行。
sub( Ere, Repl, [ In ] ) 用 Repl 参数指定的字符串替换 In 参数指定的字符串中的由 Ere 参数指定的扩展正则表达式的第一个具体值。sub 函数返回替换的数量。出现在 Repl 参数指定的字符串中的 &(和符号)由 In 参数指定的与 Ere 参数的指定的扩展正则表达式匹配的字符串替换。如果未指定 In 参数,缺省值是整个记录($0 记录变量)。
index( String1, String2 ) 在由 String1 参数指定的字符串(其中有出现 String2 指定的参数)中,返回位置,从 1 开始编号。如果 String2 参数不在 String1 参数中出现,则返回 0(零)。
length [(String)] 返回 String 参数指定的字符串的长度(字符形式)。如果未给出 String 参数,则返回整个记录的长度($0 记录变量)。

例1:gsub,sub使用

#在 info中查找满足正则表达式,/[0-9]+/ 用””替换,并且替换后的值,赋值给info 未给info值,默认是$0
[root@mysql-master ~]# awk 'BEGIN{info="this is a test2010AAAA!";gsub(/[0-9]+/,"--",info);print info}'
this is a test--AAAA!

例2:查找字符串(index使用)

[root@mysql-master ~]# awk 'BEGIN{info="this is a test2010AAAA!";print index(info,"2018")?"yes":"no found"}'
no found

例3:awk使用外部变量的三种方法

方法1. 在双引号的情况下
[root@mysql-master ~]# echo "lss linux" |awk "gsub(/lss/,\"$USER\")"
root linux
方法2. 在单引号的情况下
[root@mysql-master ~]# echo "lss linux" |awk 'gsub(/lss/,"'"$USER"'")'
root linux

# 打印出磁盘占用率大于10%的挂载点
[root@mysql-master ~]# df -h |awk '{if(int($5)>10){print $6":"$5}}'
/:12%
/boot:13%

方法3:awk自带的参数 -v (推荐)
[root@mysql-master ~]# echo "lss linux" |awk -v user=root 'gsub(/lss/,user)'
root linux
[root@mysql-master ~]# echo "lss linux" |awk -v user=root "gsub(/lss/,user)"
root linux

猜你喜欢

转载自blog.csdn.net/qq_31725371/article/details/83870686