三剑客之awk学习笔记
awk命令拼接
$0 打印源数据
ls test|awk -F '[_]' '{print "mv " $0,$1".jpg"}'
ls |awk -F '.' '{print "mv",$0,$1".jpg"}'|bash #拼接后的命令交给bash处理
ls |awk -F '.' '{print $1".jpg"}'
ls|awk -F '.' '{print $(NF -1)}'
awk指定特殊分隔符[]
如果用到特殊符号[],要用\\双反斜线转义
[root@yeahzxw tmp]# cat t3.txt |awk -F '[\\[\\]]' '{print $2}'
ERROR
WARN
INFO
ERROR
ERROR
[root@yeahzxw tmp]# cat t3.txt
[ERROR]
[WARN]
[INFO]
[ERROR]JKASDHSJKADHAJKDH JASDKJ ASJDADK
[ERROR] ASDASDFSDF121WD 23E WED2 123
awk数组
BEGIN
仅在开始处理文件中的文本之前执行一次
END
仅在文本处理完成后执行一次
不接文件时要用BEGIN初始化
打印数组
第一种-BEGIN
awk 'BEGIN{array[1]="yeahzxw";array[2]="zxw";for(i in array) print i,array[i]}'
第二种-END
awk用END时后面要接文件
awk 'BEGIN{array[1]="yeahzxw";array[2]="zxw"}END{for(i in array) print i,array[i]}' /tmp/tmp.txt
第三种-awk脚本
#!/bin/awk
BEGIN{
array[1]="one";
array[2]="two";
array[3]="three";
for(num in array)
print num,array[num]
}
注:执行是要用awk -f,不要用sh(处理文件较多时用)
[root@yeahzxw tmp]# awk -f awk.awk
1 one
2 two
3 three
引用文件中的数组
将文件中第一列作为下标,第二列作为值,放入数组,然后打印
[root@yeahzxw tmp]# cat t1.txt
1 yeahzxw
2 zxw
[root@yeahzxw tmp]# awk '{array[$1]=$2}END{for(i in array)print i,array[i]}' t1.txt
1 yeahzxw
2 zxw
awk去重
awk去重排序
S[$2]代表把第二列当做数组,S[$2]+1代表记录数组中关键字出现次数
第一种
[root@yeahzxw tmp]# awk -F "/" '{S[$2]=S[$2]+1}END{for (i in S) print i,S[i]}' t2.txt
www.123.org 2
www.123.cn 1
www.123.com 4
[root@yeahzxw tmp]# cat t2.txt
aaa/www.123.com/index.html
aaa/www.123.com/index.jpg
aaa/www.123.com/index.html
aaa/www.123.org/index.html
aaa/www.123.com/index.html
aaa/www.123.org/index.html
aaa/www.123.cn/index.html
第二种
[root@yeahzxw tmp]# awk -F "/" '{S[$2]++}END{for (i in S) print i,S[i]}' t2.txt
www.123.org 2
www.123.cn 1
www.123.com 4
------------------------------------------------------------------------------------------------------------------------
双数组去重计算并排序
[root@yeahzxw tmp]# awk '{NUM[$1]++;NAME[$1]=NUM[$1]+$2}END{for ( i in NUM)print i,NAME[i]}' t4.txt |sort -rn -k2|head
a 10
d 7
g 5
e 4
b 3
f 2
c 2
[root@yeahzxw tmp]# cat t4.txt
a 1
a 2
b 3
c 1
d 6
e 3
f 1
d 5
b 1
g 4
a 7
awk条件和循环
NR
ifconfig|awk 'NR==2' #指定行号
ifconfig|awk 'NR>=2 && NR<=5' #获取从第几行到第几行的数据
FS,OFS
-v FS=':' -v OFS='#' #指定输入分隔符为:(可以当变量引用),输出分隔符为#
RS,ORS
-v RS=':' -v ORS='#' #指定输入单行(记录)分隔符为:,输出分隔符为#
if判断
判断文件中第三列是否大于等于100,如果大于等于100则打印<=100,$3
awk -F: '{if($3<=100){print "<=100",$3}else if ($3<=100){print "<=1000",$3}else if ($3>=1000){print ">=1000",$3}}' /etc/passwd
例:判断磁盘可用率如果低于10%,就打印
[root@yeahzxw tmp]# df -h|awk '/^\/dev\//{if($5<30){print $1" is <30"}else if($5>30){print $1" is >30"}}' /dev/vda1 is >30
while循环
-v定义变量
例:从1加到100
[root@yeahzxw tmp]# awk -v i=1 -v sum=0 'BEGIN{while(i<=100){sum+=i;i++};print sum}'
5050
将变量放到BEGIN里
[root@yeahzxw ~]# awk 'BEGIN{i=1;num=0;while(i<=100){num+=i;i++}print num}'
5050
for循环
例:从1加到100
[root@yeahzxw tmp]# awk -v num=0 'BEGIN{for(i=1;i<=100;i++){sum+=i}print sum}'
5050
for,while练习题
将文件中数字用awk计算相加的结果
[root@yeahzxw tmp]# cat t5.txt
1 2 3 4 5 6
for循环做法:
[root@yeahzxw tmp]# cat t5.txt |awk -v sum=0 '{for (i=1;i<=NF;i++){sum+=i}print sum}'
21
while循环做法:
[root@yeahzxw tmp]# cat t5.txt |awk -v i=1 -v sum=0 '{while(i<=NF){sum+=i;i++}print sum}'
awk内置函数
rand()
取0-1之间随机数
awk 'BEGIN{print rand()}'
srand()
配合rand使用
awk 'BEGIN{srand();print rand()}'
int()
取整
awk 'BEGIN{srand();print int(rand()*100)}'
length()
长度
awk 'BEGIN{print length("zxw")}'
sub()
对字符串r,替换为s
echo "11:11 11:11"|awk 'sub(/:/,"-",$1)'
gsub()
对字符串r,替换为s---贪婪模式
echo "11:11 11:11"|awk 'gsub(/:/,"-",$1)'
split()
将某一列中的数据以:切割,并将切割结果作为数组(ip)
netstat -nt|awk '/^tcp/{split($5,ip,":");count[ip[1]]++}END{for(i in count)print i,count[i]}'
system()
调用系统命令
awk 'BEGIN{system("ls")}'
没啥用,随便玩的
[root@yeahzxw tmp]# awk 'BEGIN{print "-------------------------\n""user"" | ""uid\n""-------------------------\n"}{print $1" "$2}' t4.txt
-------------------------
user | uid
-------------------------
a 1
a 2
b 3
c 1