awk第二部分

条件判断 if-else

使用场景:对awk取得的整行或某个字段做条件判断

if(condition){statement;…}[else statement]
if(condition1){statement1}else if(condition2){statement2}else if(condition3)
{statement3}...... else {statementN}

条件判断 switch-case

awk 中的switch分支语句功能较弱,只能进行等值比较或正则匹配。 各分支结尾需使用break来终止

循环 while

条件“真”,进入循环;条件“假”,退出循环 使用场景: 对一行内的多个字段逐一类似处理时使用;对数组中的各元素逐一处理时使用

循环 do-while

无论真假,至少执行一次循环体

循环 for

特殊用法:能够遍历数组中的元素

for(var in array) {for-body}
[root@ubuntu2204 ~]# awk 'BEGIN{ arr[0]=123;arr[1]=456;for(i in arr){ print 
i"==>"arr[i] };}'
0==>123

计算当前文件的总和

# cat abc.txt
1 2 3 4 5
#cat abc.txt |awk '{for(i=1;i<=NF;i++){sum+=$i};print sum}'
15
#cat abc.txt|tr ' ' + |bc
15
#sum=0;for i in `cat abc.txt`;do let sum+=i;done;echo $sum
15

性能比较

time (awk 'BEGIN{ total=0;for(i=0;i<=10000;i++){total+=i;};print total;}')
time (total=0;for i in {1..10000};do total=$(($total+i));done;echo $total)
time (for ((i=0;i<=10000;i++));do let total+=i;done;echo $total)
time (seq -s"+" 10000|bc)

continue 和 break

continue 中断本次循环                        break 中断整个循环

next

next 可以提前结束对本行处理而直接进入下一行处理(awk自身循环)

数组 awk的数组为关联数组

index-expression

利用数组,实现 k/v 功能

可使用任意字符串;字符串要使用双引号括起来

如果某数组元素事先不存在,在引用时,awk会自动创建此元素,并将其值初始化为“空串”

若要判断数组中是否存在某元素,要使用“index in array”格式进行遍历

封掉查看访问日志中连接次数超过1000次的IP

[root@ubuntu2204 ~]# awk '{ip[$1]++}END{for(i in ip){if(ip[i]>=1000)
{system("iptables
-A INPUT -s "i" -j REJECT")}}}' nginx.access.log-20200428

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

数值处理

rand() 		#返回0和1之间一个随机数
srand() 	#配合rand() 函数,生成随机数的种子
int() 		#返回整数

字符串处理

str1=(str2,str3) 	#连字符,字符串拼接
length([s]) 		#返回指定字符串的长度
sub(r,s,[t]) 		#在t中串搜索r匹配的内容,并将第一个匹配内容替换为s
gsub(r,s,[t]) 		#在t中串搜索r匹配的内容,并将匹配内容全部替换为s,即贪婪模式
split(s,array,[r]) 	#以r为分隔符,切割串s,并将结果保存至array数组中,索引值为1,2,…

统计用户名的长度

[root@ubuntu2204 ~]# cut -d: -f1 /etc/passwd | awk '{print length()}'
[root@ubuntu2204 ~]# awk -F: '{print length($1)}' /etc/passwd

调用shell命令

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

[root@ubuntu2204 ~]# awk 'BEGIN{system("hostname")}'
rocky86.m51.magedu.com
[root@ubuntu2204 ~]# awk 'BEGIN{score=100; system("echo your score is " score) 
}'
your score is 100
[root@ubuntu2204 ~]# 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")}}}'

时间函数

time() #当前时间到1970年1月1日的秒数
strftime() #指定时间格式 

[root@ubuntu2204 ~]# awk 'BEGIN{print systime()}'
1609917829
[root@ubuntu2204 ~]# awk 'BEGIN{print systime();system("date +%s")}'
1661687319
1661687319
[root@ubuntu2204 ~]# awk 'BEGIN{print strftime("%Y-%m-
%dT%H:%M",systime()-3600)}'
2021-01-06T14:24
[root@ubuntu2204 ~]# awk 'BEGIN{print strftime("%Y-%m-%d %H:%M:%S");system("date 
\"+%Y-%m-%d %H:%M:%S\"")}'
2022-08-28 19:51:34
2022-08-28 19:51:34

自定义函数

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

awk 脚本

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

向awk脚本传递参数

awkfile  var=value  var2=value2... Inputfile

注意:

上面格式变量在BEGIN过程中不可用。直到首行输入完成以后,变量才可用

可以通过-v 参数,让awk在执行BEGIN之前得到变量的值

命令行中每一个指定的变量都需要一个-v参数

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@ubuntu2204 ~]# awk -F'[ .]' '{print $2}' host_list.log >> host_list.log 
[root@ubuntu2204 ~]# cat host_list.log 
1 www.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
www
blog
study
linux
python

2.统计/etc/fstab文件中每个文件系统类型出现的次数

参考答案:

[root@rocky86 ~]# awk -F' +' '/^UUID/{fs[$3]++}END{for(i in fs){print i,fs[i]}}' 
/etc/fstab
swap 1
ext4 3
[root@rocky86 ~]# awk -F' +' '/^UUID/{print $3}' /etc/fstab |uniq -c
      3 ext4
      1 swap

3.统计/etc/fstab文件中每个单词出现的次数

参考答案;

[root@rocky86 ~]# awk -F"[^[:alpha:]]" '{for(i=1;i<=NF;i++)word[$i]++}END{for (a 
in word)if(a !="") print a,word[a]}'   /etc/fstab

4.提取出字符串Yd$C@M05MB%9&Bdh7dq+YVixp3vpw中的所有数字

答案:

[root@rocky86 ~]# echo 'Yd$C@M05MB%9&Bdh7dq+YVixp3vpw' | awk '{gsub(/[^0-
9]/,"");print $0}'
05973
[root@rocky86 ~]# echo 'Yd$C@M05MB%9&Bdh7dq+YVixp3vpw' |awk -F "" 
'{for(i=1;i<=NF;i++){if ($i ~ /[[:digit:]]/){str=$i; str1=(str1 str)}};print 
str1}'
[root@rocky86 ~]# echo 'Yd$C@M05MB%9&Bdh7dq+YVixp3vpw' | awk -F'[^0-9]' 
'{for(i=1;i<=NF;i++){printf "%s",$i }}'
05973

5.文件random.txt记录共5000个随机的整数,存储的格式100,50,35,89…请取出其中最大和最小的整 数

参考答案

[root@rocky86 ~]# str="";for((i=1;i<=5000;i++));do if [ $i -ne 5000 ];then 
str+="$RANDOM,";else str+=$RANDOM;fi;done;echo $str > random.txt
[root@rocky86 ~]# awk -F, '{max=$1;min=$1;for(i=1;i<=NF;i++){if($i>max)
{max=$i}else{if($i<min){min=$i}}}}END{print "最大值:"max,"最小值:"min}' 
random.txt

6.解决Dos攻击生产案例:监控当某个IP并发连接数超过100时,即调用防火墙命令封掉对应的IP,监 控频率每隔5分钟。防火墙命令为:iptables -A INPUT -s IP -j REJECT

参考答案

[root@rocky86 ~]# ss -nt | awk -F " +|:" 'NR!=1{ip[$(NF-2)]++}END{for(i in ip)
{if(ip[i]>100){system("iptables -A INPUT -s "i" -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.将以下文本文件awktest.txt中 以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|

输出的结果格式为:

106|3363120000|3368579999|30000|
310|3337000000|3362120961|10103|
311|3313460102|3362120963|39900|

参考答案:

[root@centos8 ~]#cat awktest.txt
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|
[root@rocky86 ~]# awk -F '|' 
'!/^inode/{sum[$1]+=$4;if(!begin[$1])begin[$1]=$2;else 
if(begin[$1]>$2)begin[$1]=$2;if(!end[$1])end[$1]=$3;else if(end[$1]
<$3)end[$1]=$3}END{for(i in sum)print i"|"begin[i]"|"end[i]"|"sum[i]}' 
awktest.txt
[root@rocky86 ~]# awk -F'|' -v OFS='|' '/^[0-9]/{inode[$1]++; if(!bn[$1])
{bn[$1]=$2}else if(bn[$1]>$2){bn[$1]=$2}; if(en[$1]<$3)en[$1]=$3;cnt[$1]+=$(NF1)} END{for(i in inode)print i,bn[i],en[i],cnt[i]}' awktest.txt

以上存是个人笔记   不喜勿喷   谢谢

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

白了个白i

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值