awk常用示例
1、通过awk判断系统的用户都属于什么用户:
[root@Docker ~]# awk -F ':' '{if($3 == 0 )print "超级管理员: "$1}{if($3 > 0 && $3 < 1000)print "系统用户: "$1}{if($3 >= 1000)print "自建用户:"$1}' /etc/passwd
2、显示出包含Lee和包含kevin的行的中间行
[root@oldboy_50 tmp]# cat test.txt
Allen Phillips
Green Lee
William Aiden James Lee
Angel Jack
Tyler Kevin
Lucas Thomas
Kevin
详解:
awk '/Lee/,/kevin/{print $0}' test.txt
3、awk取指定范围的列:
awk -F : '{for(i=3;i<=5;i++)printf"%s ",$i;printf"\n"}' /etc/passwd
4、如何把/etc/passwd文件里面的':' 全部替换成空格
awk '{gsub(/:/," ",$0);print $0}' passwd
sed -n "s#:# #gp" passwd
awk -F ":" -vOFS=" " '{$1=$1;print $0}' passwd
awk -F ":" -v OFS=" " '{for(i=1;i<NF;i++)printf"%s ",$i;printf"\n"}'
passwd
如果$0发生了改变(通过赋值或者替换),那么$1,$2以及NF就会被重新计算,同样的道理,
当$1或者$2被改变了,那么$0就会被重新构造,构造的方式是使用OFS
重新分隔字符
5、sed awk排除配置文件里面没用的行(配置文件里面的空行和含有#号开头的行)
sed -ri '/^ *(#.*)?$/'d sshd_config
awk '!/^ *(#.*)?$/{print $0}' sshd_config
6、如何用awk取出来最多列数所在的哪一行行号
测试环境:
[root@LornBlood tmp]# cat 1.txt
1
1 2
1 2 3
1 2 3 4
1 2 3 4 5
3 4 5 1 2 3 4 5 6 7 8
1 2 3 4 5 6
1 2 3 4 5 6 7
详解:
awk 'BEGIN{lin=0;nf=0}{if(nf < NF){lin=NR;nf=NF}}END{print "行号:"lin,"列数:"nf}' 1.txt
7、输出字符串最行的行号
测试环境:
[root@LornBlood tmp]# cat 1.txt
1
1 2
1 2 3
1 2 3 4
1 2 3 4 5
3 4 5 1 2 3 4 5 6 7 8
1 2 3 4 5 6
1 2 3 4 5 6 7
详解:
awk '{if(length($0) > LE ){LE=length($0);nr=NR}}END{print LE,nr}' /etc/passwd
8、显示Xiaoyu的捐款.每个值时都有以$开头.如$520$200$135,不允许使用sed,和OFS
cat >>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
详解:
awk '$2~/Xiaoyu/{gsub(":","$",$NF);print $NF}' reg.txt
9、生成一个随机的三位数
awk 'BEGIN{ srand() ; print int( rand() * 1000 ) }' /etc/passwd
详解:
rand如果不配合srand使用的话,产生的随机数都是固定的
rand产生的随机数范围是 0 <= rand() <1 的取三位数,我们就把rand()* 1000然后在去他整数部分的值即可
srand() 必须在BEGIN模块里面
10、求一个文件里面 ‘1’ 字符出现的次数:
awk '{a=gsub(/1/,"Q");sum = sum + a ; print $0,a}END{print "一共替换了:"sum}' reg.txt
详解:
我们直接求文件里面1出现的次数不好求,我们可以利用gsub返回替换次数的特性来解答这个
11、统计这个日志文件中secure-20161219,别人一个ip地址破解了我们哪些用户的密码,一个用户被哪些IP地址破解了
awk '/Failed/ { sum[$(NF-3)" "$(NF-5)]++}END{for(i in sum) print sum[i],i}' secure-20161219 |grep [ user_name | IP ]
12、把这个两个文件都存在的用户的密码输出出来
[root@sentinel student]# head file1 file2
==> file1 <==
oldboy 1234
alex 4567
lidao 9999
==> file2 <==
001 lidao
002 alex
003 oldboy
004 oldgirl
提示:需要用到如何判断这两个文件不是一个文件。
详解:
awk 'FNR==NR{h[$1]=$2}FNR!=NR{print h[$2]}' file1 file2
awk 'FNR==NR{h[$1]=$2;next}{print h[$2]}' file1 file2
//next 满足前面这个条件就不执行后面的内容了
#!/bin/bash
for i in `awk '{print $1}' file1`
do
for j in `awk '{print $2}' file2`
do
if [ $i == $j ];then
awk '$1~/'$i'/{print $2}' file1
fi
done
done
绝望系列
每周绝望原数据文件:
id=aa&bb&type&name=cc
bb&id=aa&name=cc&type
id=aa&type&bb&name=dd
type&id=aa&cc&name=bb
id=bb&cc&type&name=bb
aa&id=bb&name=bb&type
整理并去重,得到效果:
id=aa&bb&name=cc&type
id=aa&bb&name=dd&type
id=aa&cc&name=bb&type
id=bb&cc&name=bb&type
id=bb&aa&name=bb&type
提示:awk循环、判断、变量赋值、去重机制
详解
awk -F '&' -v OFS='&' '{for(i=1;i<=4;i++)printf"%s" $i;printf "\n"}' awk.txt 实现每个遍历了
awk -F '&' -v OFS='&' '{for(i=1;i<=4;i++){if($i~/^id.$/)A=$i;if($i~/^[a-z]{2}$/)B=$i;if($i~/^name./)C=$i;if($i~/^type$/)D=$i}print A,B,C,D}' awk.txt
echo {a..z} | xargs -n 1 >awk.txt
利用awk去除g所在行的上下5行
for j in awk '/^j$/{for(i=NR-5;i<=NR+5;i++)print i}' 1.txt;do awk -v j=$j 'NR==j{print $0}' 1.txt;done