awk的使用

awk

-v设置变量

-F 指定分隔符

内置变量

FS:输入字段分隔符,默认为空白字符,读入内容的分隔符

OFS:输出字段的分隔符

RS:指定行(记录)分隔符

ORS:输出记录分隔符

NF:字段数量

NR:记录的数量

ARGC:命令行参数的个数

ARGV:数组,保存的是命令行所有的参数

 

例1:不依赖文件和标准输入

[root@centos7 ~]#awk ‘BEGIN{print “haha”}’

haha

BEGIN表示只处理一次,后面可以不处理文件

例2:做数值运算

[root@centos7 ~]#awk ‘BEGIN{print 2^10}’

1024

例3:打印/etc/passwd文件中的用户名和uid,输出以:号做分隔符

[root@centos7 ~]#awk -F: ‘{print $1″:”$3}’ /etc/passwd

root:0

bin:1

daemon:2

 

指定输入分隔符

awk -v FS=: ‘{print $1FS$3}’ /etc/passwd

FS是awk里的变量,

[root@centos7 ~]#fs=”:”;awk -v FS=$fs ‘{print $1FS$3}’ /etc/passwd

 

指定输入和输出分隔符

[root@centos7 ~]#fs=”:”;awk -v FS=$fs -v OFS=: ‘{print $1,$3}’ /etc/passwd

 

例:取分区名和利用率

[root@centos7 data]#df | grep ^/dev/sd | awk -v FS=”%” ‘{print $1}’ | awk ‘{print $1,$5}’

/dev/sda2 37

/dev/sda3 3

/dev/sda1 16

 

例:NF字段数量

[root@centos7 data]#awk -v FS=”:” ‘{print NF,$NF}’ /etc/passwd

7 /sbin/nologin

7 /bin/bash

7 /bin/bash

例: 打印倒数第二个字段

[root@centos7 data]#awk -v FS=”:” ‘{print $(NF-1)}’ /etc/passwd

/root

/bin

/sbin

/var/adm

/var/spool/lpd

/sbin

/sbin

/sbin

 

例:NR记录数量

[root@centos7 ~]#awk -v FS=”:” ‘{print NR,$1}’ /etc/passwd

1 root

2 bin

3 daemon

4 adm

5 lp

6 sync

 

awk -v FS=”:” ‘{print NR,$1}’ /etc/passwd /etc/fstab 假如处理的是两个文件,那么他们记录数量方式是一起编号

awk -v FS=”:” ‘{print FNR,$1}’ /etc/passwd /etc/fstab 则各自有各自的编号

 

例:参数的个数ARGC

[root@centos7 ~]#awk ‘{print ARGC}’ /etc/passwd /etc/inittab

3

3

3

3

例:数组ARGV

[root@centos7 ~]#awk ‘{print ARGV[1]}’ /etc/issue /etc/fstab

/etc/issue

/etc/issue

/etc/issue

/etc/issue

/etc/issue

/etc/issue

 

awk变量自定义变量

定义方式

1.-v var=value

[root@centos7 ~]#awk -v name=wang ‘BEGIN{print name}’

wang

 

2.在program中直接定义

[root@centos7 ~]#awk ‘BEGIN{name=”wang”;print name}’

wang

 

例:-f调用文件

[root@centos7 data]#cat scripts

{print $1,$3}

[root@centos7 data]#awk -v FS=”:” -v OFS=”=” -f /data/scripts /etc/passwd

root=0

bin=1

daemon=2

adm=3

lp=4

 

printf命令

格式化输出:printf “FORMAT”, item1, item2, …

(1) 必须指定FORMAT

(2) 不会自动换行,需要显式给出换行控制符,\n

(3) FORMAT中需要分别为后面每个item指定格式符

格式符:与item一一对应

%c: 显示字符的ASCII码

%d, %i: 显示十进制整数

%e, %E:显示科学计数法数值

%f:显示为浮点数

%g, %G:以科学计数法或浮点形式显示数值

%s:显示字符串

%u:无符号整数

%%: 显示%自身

修饰符:

#[.#]:第一个数字控制显示的宽度;第二个#表示小数点后精度,%3.1f

-: 左对齐(默认右对齐) %-15s

+:显示数值的正负符号 %+d

 

[root@centos7 data]#awk -F: ‘BEGIN{print “user                          uid\n———————————–“}{printf “%-20s:%10d\n”,$1,$3}END{print “———————————–“}’ /etc/passwd

 

模式匹配符:

~:左边是否和右边匹配包含 !~:是否不匹配

示例:

awk –F: ‘$0 ~ /root/{print $1}‘ /etc/passwd

awk ‘$0~“^root”‘ /etc/passwd

awk ‘$0 !~ /root/‘ /etc/passwd

awk –F: ‘$3==0’ /etc/passwd

 

例:显示用户id号大于1000小于1010的用户名和id

[root@centos7 data]#awk -F: ‘$3>=1000 && $3<=1010{print $1,$3}’ /etc/passwd

wang 1000

bash 1001

testbash 1002

basher 1003

sh 1004

nologin 1005

haha 1006

hehe 1007

aa 1008

bb 1009

feng 1010

 

例:取反

[root@centos7 data]#awk -F: ‘! ($3>=1000){print $1,$3}’ /etc/passwd

 

在awk中1为真,0为假

[root@centos7 data]#awk ‘BEGIN{print !i}’

1

[root@centos7 data]#awk ‘BEGIN{i=0;print !i}’

1

[root@centos7 data]#awk ‘BEGIN{i=2;print !i}’

0

[root@centos7 data]#awk ‘BEGIN{i=”abc”;print !i}’

0

 

awk控制语句if-else

语法:if(condition){statement;…}[else statement]

if(condition2){statement1}else if(condition2){statement2}else{statement3}

 

例:打印shell为/sbin/nologin的用户

[root@centos6 data]#awk -v FS=: ‘{if($NF == “/sbin/nologin”)print $1}’ /etc/passwd

bin

daemon

adm

lp

 

例2:

awk ‘BEGIN{ test=100;if(test>90){print “very good“}else if(test>60){ print “good”}else{print “no pass”}}’

 

awk控制语句

语法:while(condition){statement;…}

使用场景:

对一行内的各个字段逐一类似处理时使用

对数组中的各元素逐一处理时使用

 

例:打印某行单词,和字符长度

[root@centos6 data]#awk ‘/^[[:space:]]+kernel.*/{i=1;while(i<=NF){print $i,length($i);i++}}’ /etc/grub.conf

kernel 6

/vmlinuz-2.6.32-696.el6.x86_64 30

ro 2

root=UUID=50e87f34-5611-4315-9a53-21afd7fd859a 46

rd_NO_LUKS 10

rd_NO_LVM 9

LANG=en_US.UTF-8 16

rd_NO_MD 8

SYSFONT=latarcyrheb-sun16 25

length($i)表示变量$i字符的长度

 

例2:

[root@centos6 data]#awk ‘/^[[:space:]]+kernel.*/{i=1;while (i<=NF){if(length($i)>=10){print $i,length($i)};i++}}’ /etc/grub.conf

/vmlinuz-2.6.32-696.el6.x86_64 30

root=UUID=50e87f34-5611-4315-9a53-21afd7fd859a 46

rd_NO_LUKS 10

LANG=en_US.UTF-8 16

SYSFONT=latarcyrheb-sun16 25

crashkernel=auto 16

KEYBOARDTYPE=pc 15

KEYTABLE=us 11

(hd0,0)/vmlinuz-2.6.32-696.el6.x86_64 37

root=/dev/sda2 14

 

awk控制语句do-while循环

语法:do{statement;…}while(condition)

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

 

示例:

awk ‘BEGIN{ total=0;i=0;do{ total+=i;i++;}while(i<=100);print total}’

 

 awk控制语句for循环

语法:for(expr1;expr2;expr3{statement}

 

例1:

[root@centos6 data]#time awk ‘BEGIN{for(i=1;i<=100000000;i++)sum=sum+i;print sum}’

5000000050000000

 

real 0m9.548s

user 0m9.548s

sys   0m0.003s

time命令,测试awk性能

 

 

break和continue

awk ‘BEGIN{sum=0;for(i=1;i<=100;i++){if(i%2==0)continue;sum+=i}print sum}‘

awk ‘BEGIN{sum=0;for(i=1;i<=100;i++){if(i==66)break;sum+=i}print sum}‘

 

next:

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

awk -F: ‘{if($3%2!=0) next; print $1,$3}’ /etc/passwd

 [root@centos6 data]#awk -F: ‘{if($3>10 && $3<20)print $1,$3}’ /etc/passwd

operator 11

games 12

gopher 13

ftp 14

 

 awk数组

关联数组:array[index-expression]

index-expression:

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

(2) 如果某数组元素事先不存在,在引用时,awk会自动创建此元素,并将其值初始化为“空串”,若要判断数组中是否存在某元素,要使用“index in array”格式进行遍历

 

若要遍历数组中的每个元素,要使用for循环

for(var in array) {for-body}

注意:var会遍历array的每个索引

 

例1:

[root@centos7~]#awk’BEGIN{name[“haha”]=”wang”;name[“hehe”]=”zhao”;name[“heihei”]=”zhang”;for(i in name)print name[i] }’

zhao

zhang

wang

 

ab -c 100 -n 2000 http://192.168.67.130/并发访问

 

例:

[root@centos7 ~]#netstat -tan | awk ‘/^tcp/{state[$NF]++}END{for(i in state){print i,state[i]}}’

LISTEN 9

ESTABLISHED 1

TIME_WAIT 1999

例:

[root@centos7 ~]#cat /var/log/httpd/access_log | awk ‘/^[0-9]+/{ip[$1]++}END{for (i in ip){print i,ip[i]}}’

172.20.109.152 10

192.168.67.132 4004

 

列:把访问量大于1000的IP放入防火墙

[root@centos7 data]#awk ‘/^[0-9]/{ip[$1]++}END{for(i in ip){if(ip[i]>1000)print i}}’ /var/log/httpd/access_log | while read ip;do iptables -A INPUT -s $ip -j REJECT;done

 

例:统计一个文件的单词数

[root@centos7 data]#awk ‘{for(i=1;i<=NF;i++){word[$i]++}}END{for(j in word)print j,word[j]}’ /etc/fstab

本文来自投稿,不代表Linux运维部落立场,如若转载,请注明出处:http://www.178linux.com/99070

发表评论

登录后才能评论

This site uses Akismet to reduce spam. Learn how your comment data is processed.

联系我们

400-080-6560

在线咨询:点击这里给我发消息

邮件:1823388528@qq.com

工作时间:周一至周五,9:30-18:30,节假日同时也值班