码迷,mamicode.com
首页 > 其他好文 > 详细

awk

时间:2017-10-19 12:33:36      阅读:222      评论:0      收藏:0      [点我收藏+]

标签:awk


AWK


1.print

要点

1)逗号分隔符

2)输出的各item可以字符串,也可以是数值,当前记录的字段,变量或awk的表达式

3)如省略item,相当于print $0


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

awk -F ‘:‘ ‘{print $1}‘ /etc/passwd

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


例:

[root@web1 ~]# cat /var/log/secure |awk ‘/Failed password/{print "攻击我的IP:",$11}‘ >ip.txt

cat ip.txt

攻击我的IP: 192.168.4.254

攻击我的IP: 192.168.4.20


[root@web1 ~]# cat /var/log/secure |awk ‘/Failed password/{print "攻击我的IP:",$11}‘|uniq -c

      3 攻击我的IP: 192.168.4.254

      1 攻击我的IP: 192.168.4.20


[root@web1 ~]# awk ‘BEGIN{x=0}/bash$/{x++}END{print x}‘ /etc/passwd

2


[root@web1 ~]# awk ‘BEGIN{x=0}{if(/bash$/){x++};y++}END{print "bash-user:"x,"\t","nogolin-user:",y}‘ /etc/passwd

bash-user:2 nogolin-user: 43


[root@web1 ~]# awk ‘{if(/bash$/){x++};y++}END{print "bash-user:"x,"\t","nogolin-user:",y}‘ /etc/passwd

bash-user:2 nogolin-user: 43


[root@web1 ~]# awk ‘BEGIN{x=11;print x+12}‘

23

[root@web1 ~]# awk ‘BEGIN{x=11;print x*12}‘

132

[root@web1 ~]# awk ‘BEGIN{x=11;print 34.5+1.2}‘

35.7

[root@web1 ~]# awk ‘BEGIN{print 34.5+1.2}‘

35.7


[root@web1 ~]# echo "11 22 33 44"|awk ‘{print $1+$2+$3+$4}‘

110


[root@web1 ~]# ifconfig| head -2|awk ‘/inet/{print $2}‘

192.168.4.10


[root@web1 ~]# awk -F[:] ‘{print "用户名:",$1,"\t","UID:",$3,"\t","宿主目录:",$6}END{print "总行数:"NR}‘ /etc/passwd

用户名: root UID: 0 宿主目录: /root

用户名: bin        UID: 1 宿主目录: /bin

...

总行数:43


[root@web1 ~]# awk -F[:] ‘BEGIN{print "USER","\t","UUID","\t","HOME"}{print $1,"\t",$3,"\t",$6}END{print "总行数:"NR}‘ /etc/passwd

USER UUID HOME

root 0 /root

bin 1 /bin

...

总行数:43


[root@web1 ~]# df -h|awk  ‘$6=="/"{print $5}‘|awk -F% ‘{print $1}‘

38


[root@web1 ~]# ifconfig eth0|awk ‘$1=="inet"{print $2}‘

192.168.4.10


[root@web1 ~]# awk -F: ‘{if($3>=1000){x++}else{y++}}END{print x,y}‘ /etc/passwd

2 41

[root@web1 ~]# awk -F: ‘{for(i=1;i<=NR;i++){if($3>=1000){x++}else{y++}}}END{print x,y}‘ /etc/passwd

77 869


[root@web1 ~]# awk ‘{print}‘ a.txt

10

20

30

40

[root@web1 ~]# awk ‘EBGIN{sum=0}{for(i=1;i<=NR;i++){sum+=$i}}END{print sum}‘ a.txt

100


[root@room8pc205 桌面]# awk ‘$1~/127/||$1~/192/{print}‘ /etc/hosts

127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4

192.168.4.1 www.a.com


[root@room8pc205 桌面]# seq 100 |awk ‘$1%7==0&&$1~/7/‘

7

70

77

[root@room8pc205 桌面]# seq 100 |awk ‘$1%7==0||$1~/7/‘

7

14

17

...

98


[root@web1 ~]# awk ‘{print $10}‘ /var/log/httpd/access_log|awk ‘BEGIN{sum=0}{i=1;while(i<=NF){sum+=$i;i++}}END{print sum}‘

91


[root@web1 ~]# awk -F: ‘BEGIN{i=0}{while(i<=NF){if($i~/root/){j++};i++}}END{print j}‘ /etc/passwd

4


[root@web1 ~]# awk -F: ‘{for(i=1;i<=NF;i++){if($i~/root/){j++}}}END{print j}‘ /etc/passwd

4


[root@mariadb-ser30 soft]# ifconfig eth0|awk ‘/inet /{print $2}‘|awk -F ‘.‘ ‘{for(i=1;i<=NF;i++){print $i}}‘|awk ‘{for(j=1;j<=NF;j++){sum=sum+$j}}END{print sum}‘

394

[root@mariadb-ser30 soft]# ifconfig eth0|awk ‘/inet /{print $2}‘|awk -F ‘.‘ ‘{for(i=1;i<=NF;i++){print $i}}‘|awk ‘{j=1;while(j<=NF){sum+=$j;j++}}END{print sum}‘

394

[root@mariadb-ser30 soft]# echo $((192+168+4+30))

394


[root@room8pc205 桌面]# cat a.txt

10 40 20 30

30 10 20 40

10 30 20 40

[root@room8pc205 桌面]# awk ‘BEGIN{sum=0}{i=1;while(i<=NF){sum+=$i;i++}}END{print sum}‘ a.txt

300


[root@room8pc205 桌面]# cat aaa.log

-

-

-

-

-

-

-

3985

4234

209

3985

-

-

[root@room8pc205 桌面]# awk ‘{i=1;while(i<=NF){if($i=="-"){x++}else{sum+=$i};i++}}END{print x,sum}‘ aaa.log

9 12413


[root@web20 ~]# awk ‘BEGIN{sum=0}{if($10~/-/){x++}else{sum+=$10}}END{print sum}‘ /var/log/httpd/access_log 

119562622



[root@web20 ~]# cat b.txt

10

20

30

40

[root@web20 ~]# awk ‘BEGIN{sum=0}{sum+=$1}END{print sum}‘ b.txt

100

[root@web20 ~]# 


[root@web20 ~]# awk ‘BEGIN{a[‘tom‘]="tom";a[1]="jerry";a[2]="you";print a[tom],"\n",a[1],"\n",a[2]}‘

tom 

 jerry 

 you


[root@web20 ~]# who |awk ‘{W[$1]++}END{for(i in W){print i,W[i]}}‘ 

user 1

root 3



[root@web20 ~]# awk ‘{IP[$1]++}END{for(i in IP){print i,IP[i]}}‘ /var/log/httpd/access_log 

192.168.4.30 10000

192.168.4.5 10001

192.168.4.254 10004

::1 3

[root@web20 ~]# awk ‘{IP[$1]++}END{for(i in IP){print i,IP[i]}}‘ /var/log/httpd/access_log |awk ‘$2>500{print  $1,$2}‘

192.168.4.30 10000

192.168.4.5 10001

192.168.4.254 10004



[root@web20 ~]# echo $((3985*6))

23910

[root@web20 ~]# cat a.txt

-

3985

3985

3985

3985

3985

3985

-

-

-

[root@web20 ~]# awk ‘BEGIN{sum=0}{i=1;while(i<=NF){if($1~/-/){x++}else{sum+=$i};i++}}END{print sum}‘ a.txt

23910



2.变量

内建变量

FS:输入默认为空白字符

OFS:输出默认为空白字符

RS:输入时的换行符

ORS:输出时的换行符


awk -v RS=‘ ‘ ‘{print }‘ /etc/passwd

awk -v RS=‘ ‘ -v ORS=‘#‘ ‘{print }‘ /etc/psswd

NF:字段数量

awk ‘{print NF}‘ /etc/pass.txt #显示变量数量

awk ‘{print $NF}‘ /etc/pass.txt #打印数量每一行

awk -F: ‘{print NR,NF}‘ /etc/passwd


NR:统计行数

awk ‘{print NR}‘ /etc/pass.txt  #对一个文件进行统计行数

  awk ‘{print FNR}‘ /etc/passwd /etc/fstab  #对各文件分别计数

FILENAME:显示当前文件名

awk ‘{print FILENAME}‘ /etc/passwd

ARGC:命令行参数的个数

awk ‘BEGIN{print ARGC}‘ /etc/passwd /etc/fstab


ARGV:数组,保存的是命令行中所给定的各参数


awk ‘BEGIN{print ARGV[0]}‘ /etc/passwd /etc/fstab 

  

awk ‘BEGIN{print ARGV[1]}‘ /etc/passwd /etc/fstab 


awk ‘BEGIN{print ARGV[2]}‘ /etc/passwd /etc/fstab 

 


自定义变量

1) -v var=value

  变量名加变量值

awk -v test=‘hello work‘ ‘BEGIN{print test}‘

awk ‘BEGIN{test="hello work";print test}‘

2)在program中直接定义


3.printf 命令

格式化输出:printf 

1)format必须给出

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

3)format中需要分别为后面的每个item指定一个格式化符号

格式符

%c:显示字符的ASCII码

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

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

%f:显示为浮点数

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

%u:无符号整数

%%显示%自身

%s:显示字符串


awk -F: ‘{printf "username:%s\n",$1}‘ /etc/passwd


修饰符

#[.#]:第一个数字控制显示的宽度

%3.1f

-:左对齐

+:显示数值的符号

4.操作符

算术操作符

+ - * / ^ %

-x

+x:转换为数值


字符串操作符:没有符号的操作符,字符串的连接

赋值操作符:

= += -= *= /= %= ^=

++ --


比较操作符

> >= < <= != ==

 

模式匹配符


~ :是否匹配

!~ :是否不匹配

逻辑操作符:

&&

||

!


函数调用:

function_name(argu1,argu2,...)

条件表达式:

selector? if-true-expression: if-false-expression


awk -F: ‘{$3>=1000?usertype="common user":usertype="sysadmin or sysuser";printf "%15s:%s\n",$1,usertype}‘ /etc/passwd


5.pattern

1)empty空模式,匹配任意行

2)/regular expression/:仅处理能够被此处的模式匹配到行

    awk ‘/^UUID/{print $1}‘ /etc/fstab

            awk ‘!/^UUID/{print $1}‘ /etc/fstab  #取反

3)relational expression:关系表达式,结果“真”“假”,结果为“真”才会被处理

真:结果为非0值,非空字符串

awk -F: ‘$NF=="/bin/bash"{print $1,$NF}‘ /etc/passwd

awk -F: ‘$NF~/bash$/{print $1,$NF}‘ /etc/passwd


4)line ranges:行范围  #不支持直接给出数字的格式

/pat1/,/pat2/

awk -F: ‘/^root/,/^adm/{print $1 }‘ /etc/passwd

awk -F: ‘NR>=2&&NR<=5{print $1 }‘ /etc/passwd


5)BEGIN/END模式

BEGIN{}:仅在开始处理文件中的文本之前执行一次

END{}:仅在文本处理完成这后执行一次


6.常用的action

1)expressions

2)control statements: if ,while for 等

3)compound statements: 组合语句

4)input statements

5)output statements


7.控制语句

if(condition){statements}

if(condition){statements} else {statements}

while(condition){statements}

do {statements} while(condition)

for(expr1;expr2;expr3){statements}

break

continue

delete array[index]

delete array

exit

{statements}


1)if -else

语法:if(condition) statements [else statements]

awk -F: ‘{if ($3>=500){print $1}else{print "aaa"}}‘ /etc/passwd

awk -F: ‘{if ($3>=500){print "common user:"$1}else{print "root or sysuser:"$1}}‘ /etc/passwd

awk -F: ‘{if ($3>=500){printf "common user:%s\n",$1}else{printf "root or sysuser:%s\n",$1}}‘ /etc/passwd

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

awk -F: ‘{if($NF=="/bin/bash"){print $1}}‘ /etc/passwd

awk -F: ‘{if($NF=="/bin/bash"){print $1,$NF}}‘ /etc/passwd

awk -F: ‘{if(NF>5)print $0}‘ /etc/passwd

df -h| grep "/dev/sda5"|awk ‘{print $5}‘|awk -F[%] ‘{print $1}‘

df -h|awk -F[%] ‘/^\/dev/{print $1}‘|awk ‘{if($NF>40){print ">40device:"$1,$5}}‘


2)while循环

语法:while(condition)statement

条件“真”,进入循环:条件“假”,退出循环

使用场景:对一行内的多个字段逐一类似处理时使用,对数组中的各元素逐一处理时使用

length()


awk ‘/^[[:space:]]*init/{print}‘ /etc/grub.conf

awk -F: ‘$1~/root/{i=1;while(i<=NF){print $i,length($i);i++}}‘ /etc/passwd

awk -F: ‘$1~/root/{i=1;while(i<=NF){if(length($i)>=4){print $i,length($i)};i++}}‘ /etc/passwd



do-while循环

语法:do statement while(condition)

意义:到少执行一次循环体

3)for循环

语法:for(expr1;expr2;expr3)statement

for(variable assignment;condition;iteration process){for-body}

awk -F: ‘$1~/root/{for(i=1;i<=NF;i++){if(length($i)>=4){print $i,length($i)};i++}}‘ /etc/passwd

for特殊用法:

能够遍历数组中的元素:

语法:for(var in array){for-body}

4)switch语句

语法:switch(expression){case value1 or /regexp/:statement;case value2 or /regexp/:statement;...;default:statement}


5)break和continue

break[n]

continue

6)next

提前结束对本行的处理而直接进入下一行

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

8.array

关联数组:array[index-expression]

index-expression:

1)可使用任意字符串,字符串要使用双引号

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

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

weekdays[mon]="monday"

awk ‘BEGIN{weekdays["mon"]="monday";weekdays["tue"]="tuesday";print weekdays["mon"]}‘

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

for(var in array) {for-body}

awk ‘BEGIN{weekdays["mon"]="monday";weekdays["tue"]="tuesday";for(i in weekdays){print weekdays[i]}}‘

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


state["LISTEN"]++

state["ESTABLISHED"]++


netstat -tln|awk ‘{aa[$6]++}END{for(i in aa){print i,aa[i]}}‘

awk  ‘{ip[$1]++}END{for(i in ip){print i,ip[i]}}‘ /var/log/httpd/access_log


练习:统计/etc/fstab文件每个文件系统类型出现的次数

cat /etc/fstab |awk ‘{Type[$3]++}END{for(i in Type){print i,Type[i]}}‘

练习:指定每个单词出现的次数 #以空格为分格符

awk ‘{for(i=1;i<=NF;i++){count[$i]++}}END{for(i in count){print i,count[i]}}‘ /etc/fstab

9.函数

1)内置函数

数值处理:

rand():返回0和1之间的随机数

字符串处理:

length([s]):返回指定字符串的长度

sub(r,s[t]):以r表示的模式来查找t所表示的字符串的匹配的内容,并将鞭第一次出现替换为s所表示的内容

split(s,a[,r]):以r为分隔符切割字符s,并将切割后的结果保存至a所表示的数组中

netstat -tan|awk ‘/^tcp\>/{split($5,ip,":");count[ip[1]]++}END{for(i in count){print i,count[i]}}‘


2)自定义函数



例:


awk -F: ‘{print NF}‘ a.txt 

awk -F: ‘{print NR}‘ a.txt

if

awk -F: ‘{if($3>=500){print $1}}‘ /etc/passwd

awk -F: ‘{if($1~/root/){print}}‘ /etc/passwd

awk -F: ‘{if($3>=500){i++}else{j++}}END{print i,j}‘ /etc/passwd

awk -F: ‘{if($3>=500){i++}else{j++}}END{print "user:",i,"\t","system user:",j}‘ /etc/passwd

while if

awk -F: ‘{i=1;while(i<=NF){if($i=="root"){x++};i++}}END{print x,i}‘ a.txt 

数组

在awk中定义数组,一定要加双引号

awk ‘{print $1}‘ /var/log/httpd/access_log |sort  |uniq -c

awk ‘BEGIN{a[0]="abc";print a[0]}‘

awk ‘BEGIN{a[aq]="abc";print a[aq]}‘

awk ‘{IP[$1]++}END{for(i in IP){print i,IP[i]}}‘ /var/log/httpd/access_log

awk ‘{IP[$1]++}END{for(i in IP){print i,IP[i]}}‘ /var/log/httpd/access_log |sort


---------------------------------------------------------------------------------------

统计APACHE日志单IP访问请求次数

awk ‘{array[$1]++}END{for(key in array)print key,array[key]}‘ a.log


awk ‘{print $1}‘ /var/log/httpd/access_log|sort| uniq -c


计算访问日志大小

aa=$(cut -d "]" -f 1 a.log |cut -d "+" -f2 | tr "\n" "+");echo ${aa%%+}|bc


aa=$(awk ‘{print $5}‘ a.log | awk -F["]"] ‘{print $1}‘ | awk -F[+] ‘{print $2}‘|bc|tr "\n" "+")


aa=$(awk ‘{print $5}‘ a.log | awk -F["]"] ‘{print $1}‘ | awk -F[+] ‘{print $2}‘|bc|tr "\n" "+");echo ${aa%%+}|bc



grep -v "^$" b.log | awk -F[" "] ‘{aa[$1]++}END{for(i in aa){print i,aa[i]}}‘|sort


grep -v "^$" b.log | awk "{print $1}" |sort|uniq -c


for i in $aa;do mv $i ${i%.doc}.txt ;done


for i in $aa;do mv $i ${i/.txt/.doc} ;done


cat >abc.txt <<EOF

1、192.168.1.100

2、192.168.1.88

3、172.20.100.1

4、202.96.102.133

EOF


本文出自 “12177655” 博客,谢绝转载!

awk

标签:awk

原文地址:http://12187655.blog.51cto.com/12177655/1974017

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!