2018-05-06 GNU awk 2

1、awk变量

  • 内置变量
    FS(field separate):输入字段分隔符,默认为空白字符
    OFS(output field separate):输出字段分隔符,默认为空白字符
    RS(record separate):输入记录分隔符,默认为回车换行
    ORS:输出记录的分隔符,默认为回车换行
    NF(number field ):当前行有多少列数据(这个在每行都会根据设定的分割符重新计算,默认分割符是任意连续的多个空白符)
awk '{print NF}' /etc/fstab :打印每行的最后一个字段为第几个字段,这里是数量引用,不是对应的值引用
awk '{print $NF}' /etc/fstab : 打印每行中的最后一个字段

NR(number record):记录的数量,表示当前处理的行是第几行,可以用于打印行号;
FNR:当前处理的行是当前处理文件的第几行
awk '{print FNR}' /etc/fstab /etc/inittab
FILENAME:当前文件名
ARGC:命令行参数的个数
ARGV:数组,保存的是命令行所给定的各参数

[root@centos6 yum.repos.d]#awk 'BEGIN{print ARGC,ARGV[0]}' /etc/fstab /etc/issue  ---awk是参数
3 awk
[root@centos6 yum.repos.d]#awk 'BEGIN{print ARGC,ARGV[1]}' /etc/fstab /etc/issue   ---/etc/fstab是参数
3 /etc/fstab
[root@centos6 yum.repos.d]#awk 'BEGIN{print ARGC,ARGV[2]}' /etc/fstab /etc/issue   ---/etc/issue是参数
3 /etc/issue
  • 自定义变量
    (1) -v var=value
    (2) 在program中直接定义
[root@centos6 yum.repos.d]#awk -v test="hello gawk" 'BEGIN{print test}' 
hello gawk

总结:awk中的变量引用都不用$,这里和shell里的变量引用不一样,一定要注意,并且awk中的字符串一定要加双引号,否则会把其当变量。

2、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:3表示控制后面要打印内容的宽度;1表示小数点后精度
-: 左对齐(默认右对齐)%-15s,15是定义宽度,表示要打印的列占据15个字符,-是定义左对齐
+:显示数值的正负符号%+d

示例

[root@centos6 yum.repos.d]#cat /etc/fstab 
/dev/sda1    /boot     ext4  defaults 0 0
/dev/sda2    /      ext4   defaults   0  0
/dev/sda3      /app   ext4   defaults  0 0 
[root@centos6 yum.repos.d]#awk '{printf "%s",$1}' /etc/fstab ---默认没有换行符
/dev/sda1/dev/sda2/dev/sda3
[root@centos6 yum.repos.d]#awk '{printf "%s\n",$1}' /etc/fstab ---要想换行加上\n
/dev/sda1
/dev/sda2
/dev/sda3
[root@centos6 yum.repos.d]#awk -F: '{printf "%-10s  %-10d\n",$1,$3}' /etc/passwd  ---可以实现左对齐
root        0         
bin         1         
daemon      2         
adm         3         
lp          4         
sync        5         
shutdown    6         
halt        7         
mail       
[root@centos6 yum.repos.d]#awk -F: '{printf "username:%s  uid:%d\n",$1,$3}' /etc/passwd  
----pritf双引号里面的内容规定了后面要打印内容的格式,并且是一一对应的关系,
"username:%s  对应的是$1的格式,uid:%d对应的是$3的格式
username:root  uid:0
username:bin  uid:1
username:daemon  uid:2
username:adm  uid:3
username:lp  uid:4
[root@centos6 yum.repos.d]#awk -F: '{printf "username: %-15s uid: %d\n",$1,$3}' /etc/passwd
username: root            uid: 0
username: bin             uid: 1
username: daemon          uid: 2
username: adm             uid: 3
username: lp              uid: 4

3、算术操作符

算术操作符:
x+y, x-y, x*y, x/y, x^y, x%y
-x: 转换为负数
+x: 转换为数值
赋值操作符:
=, +=, -=, *=, /=, %=, ^=
++, --
比较操作符:
==, !=,>, >=, <, <=
模式匹配符:
~:左边是否包含匹配右边
!~:是否不匹配
逻辑操作符:与&&,或||,非!
示例

[root@centos6 yum.repos.d]#awk 'BEGIN{print i++}' ---在awk里i不赋值也可以,默认情况下i=0
0
[root@centos6 yum.repos.d]#awk 'BEGIN{print ++i}'  ---先相加再赋值
1
[root@centos6 yum.repos.d]#df|awk '$0 ~ /^\/dev\/sd/ {print $1,$5}'    ---~表示左边包含右边
/dev/sda2 3%
/dev/sda1 4%
/dev/sda3 1%
[root@centos6 yum.repos.d]#df |awk '$0~ "^/dev/sd" {print $1,$5}'
/dev/sda2 3%
/dev/sda1 4%
/dev/sda3 1%
[root@centos6 yum.repos.d]#awk -F: '$0 ~ "root"{print $0}' /etc/passwd  
---表示整行是否包含root,如果包含就打印这一行
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
[root@centos6 yum.repos.d]#awk -F: '$0 ~ "^root"' /etc/passwd 
---这里没有写action,也就是{}里面的内容,默认就是打印整行
[root@centos6 yum.repos.d]#awk '$0 !~ "root"' /etc/passwd
---表示不包含root就打印
[root@centos6 yum.repos.d]#awk -F: '$3==0' /etc/passwd
root:x:0:0:root:/root:/bin/bash
---表示第三列的值是0就打印整行
[root@centos6 yum.repos.d]#awk -F: '$3>=0 && $3<=500{printf "systemuser:%s\n",$1}' /etc/passwd   ---与的关系
systemuser:root
systemuser:bin
systemuser:daemon
systemuser:adm
[root@centos6 yum.repos.d]#awk -F: '$3==0 || $3 >=1000 {print $1}' /etc/passwd    ---或的关系
root
nfsnobody
[root@centos6 yum.repos.d]#awk -F: '!($3==0){print $1}' /etc/passwd  ---非,注意($3==0)一定要用括号扩起来
bin
daemon
adm
lp
  • 三目表达式
    selector?if-true-expression:if-false-expression
    示例
[root@centos6 yum.repos.d]#awk -F: '{$3>=500?usertype="common user":usertype="sysuser or rootuser";printf "%s %s\n",usertype,$1}' /etc/passwd
[root@centos6 yum.repos.d]#awk -F: '$3>=500?usertype="common user":usertype="sysuser or rootuser"{printf "%s %s\n",usertype,$1}' /etc/passwd
这两种写法都可以,三目表达式可以放到大括号里面,也可以放到外面。

4、awk的pattern

PATTERN:根据pattern条件,过滤匹配的行,再做处理
(1)如果未指定:空模式,匹配每一行
(2) /regular expression/:仅处理能够模式匹配到的行,需要用/ /括起来

awk '/^UUID/{print $1}' /etc/fstab
awk '!/^UUID/{print $1}' /etc/fstab

(3) relational expression: 关系表达式,结果为“真”才会被处理
真:结果为非0值,非空字符串
假:结果为空字符串或0值

[root@centos6 yum.repos.d]#awk '!0' /etc/issue  
---结果为非0,打印
CentOS release 6.9 (Final)
Kernel \r on an \m
[root@centos6 yum.repos.d]#awk '" "' /etc/issue
---空也打印
CentOS release 6.9 (Final)
Kernel \r on an \m
[root@centos6 yum.repos.d]#awk '!1' /etc/issue  
结果为0就不打印
[root@centos6 yum.repos.d]#awk '""' /etc/issue
结果为空字符串也不打印

(4) line ranges:行范围
startline,endline:/pat1/,/pat2/不支持直接给出数字格式

awk -F: '/^root\>/,/^nobody\>/{print $1}' /etc/passwd
awk -F: '(NR>=10&&NR<=20){print NR,$1}' /etc/passwd

(5) BEGIN/END模式
BEGIN{}: 仅在开始处理文件中的文本之前执行一次
END{}:仅在文本处理完成之后执行一次
示例

[root@centos6 yum.repos.d]#awk -F: '$NF=="/bin/bash"{print $1,$NF}' /etc/passwd
root /bin/bash
dufu /bin/bash
[root@centos6 yum.repos.d]#awk -F: '$NF ~ "bash$"{print $1,$NF}' /etc/passwd
root /bin/bash
dufu /bin/bash
[root@centos6 yum.repos.d]#awk -F: 'BEGIN{print "user          uid\n------------------------------"}{printf "%-15s| %-10d\n",$1,$3}END{print "-----------------------\nend file"}' /etc/passwd
user          uid
------------------------------
root           | 0         
bin            | 1         
daemon         | 2         
adm            | 3         
lp             | 4         
sync           | 5         
shutdown       | 6         
halt           | 7         
mail           | 8         
uucp           | 10        
operator       | 11        
games          | 12        
gopher         | 13        
ftp            | 14        
nobody         | 99        
vcsa           | 69        
saslauth       | 499       
postfix        | 89        
sshd           | 74        
dufu           | 500       
ntp            | 38        
tcpdump        | 72        
apache         | 48        
rpc            | 32        
dbus           | 81        
rpcuser        | 29        
nfsnobody      | 65534     
-----------------------
end file
[root@centos6 yum.repos.d]#seq 10|awk '++i'    ---i没有定义,所以会被赋成0,0+1=1,所以从第一个开始就会打印
1
2
3
4
5
6
7
8
9
10
[root@centos6 yum.repos.d]#seq 10|awk 'i++'  ---第一行时i=0,所以不打印
2
3
4
5
6
7
8
9
10
[root@centos6 yum.repos.d]#seq 10|awk 'i=!i'
1
3
5
7
9
打印奇数,第一行读进来时,i=0,取非就是真,就打印,第二行
读进来时,i是真,取非就是假,假就不打印,第三行读进来时,i是
假,取非就是真,真就打印,这样只要是奇数行就是真,就打印
[root@centos6 yum.repos.d]#seq 10|awk '!(i=!i)'  ---打印偶数行
[root@centos6 yum.repos.d]#seq 10|awk '{i=!i;print i}'
1
0
1
0
1
0
1
0
1
0

5、打印从1-10的奇数和偶数的方法总结

方法一:echo打印
[root@centos6 yum.repos.d]#echo {1..10..2}
1 3 5 7 9
[root@centos6 yum.repos.d]#echo {2..10..2}
2 4 6 8 10
方法二:seq
[root@centos6 yum.repos.d]#seq -s " " 1 2 10
[root@centos6 yum.repos.d]#seq -s " " 2 2 10
方法三:sed
[root@centos6 yum.repos.d]#seq 10|sed -n '1~2p'
[root@centos6 yum.repos.d]#seq 10|sed -n '2~2p'
方法四:awk
[root@centos6 yum.repos.d]#seq 10|awk 'i=!i'
[root@centos6 yum.repos.d]#seq 10|awk '!(i=!i)'

6、awk的action

常用的action分类
(1) Expressions:算术,比较表达式等
(2) Control statements:if, while等
(3) Compound statements:组合语句
(4) input statements
(5) output statements:print等

7、awk控制语句

  • if-else
    语法:if(condition){statement;…}else{ statement}
    if(condition1){statement1}else if(condition2){statement2}
    else{statement3}
    小括号里面是条件判断,大括号里面是执行的动作
    使用场景:对awk取得的整行或某个字段做条件判断
    示例
[root@centos6 yum.repos.d]#awk -F: '{if($3>=1000){print $1,$3}}' /etc/passwd
nfsnobody 65534
[root@centos6 yum.repos.d]#awk -F: '{if($NF=="/bin/bash"){print $1,$3}}' /etc/passwd
root 0
dufu 500
[root@centos6 yum.repos.d]#awk '{if(NF>5){print $0}}' /etc/fstab 
[root@centos6 yum.repos.d]#awk -F: '{if($3>=500){printf "commonuser:%-15s\n",$1}else{printf "systemuser: %-15s\n",$1}}' /etc/passwd
systemuser: root           
systemuser: bin            
systemuser: daemon         
systemuser: adm 
[root@centos6 yum.repos.d]#awk -F: '{if($3>=500)printf "commonuser:%-15s\n",$1;else printf "systemuser: %-15s\n",$1}' /etc/passwd ---上面也可以用这种写法
[root@centos6 yum.repos.d]#df |awk -F% '/^\/dev\/sd/{print $1}'|awk '$NF>=80{print $1,$5}'
[root@centos6 yum.repos.d]#awk 'BEGIN{test=100;if(test>90){print "very good"}else if(test>60){print "good"}else{print "no pass"}}'
very good
[root@redhat7 script]#echo {1..10}|awk '{i=1;while(i<=NF){ if($i%2==0){print $i,"oushu"}else {print $i,"jishu"};i++}}'
  • while
    while循环
    语法:while(condition){statement;…}
    小括号里面是条件判断,大括号里面是在这种条件下执行的动作
    条件“真”,进入循环;条件“假”,退出循环
    使用场景:
    对一行内的多个字段逐一类似处理时使用
    对数组中的各元素逐一处理时使用
    示例
[root@centos6 yum.repos.d]#awk 'BEGIN{print length("xxxxxxx")}'
7
---length(),小括号里面是字符串,可以显示字符串的长度,注意如果
是字符串一定要加双引号,如果是变量不加双引号。
[root@redhat7 rules.d]#awk '/^[[:space:]]*linux16/{i=1;while(i<=NF){print $i,length($i);i++}}' /etc/grub2.cfg 
linux16 7
/vmlinuz-3.10.0-693.el7.x86_64 30
root=UUID=1ef020e7-9a49-4a5d-ae32-fb03caef3f29 46
ro 2
crashkernel=auto 16
rhgb 4
quiet 5
LANG=en_US.UTF-8 16
linux16 7
/vmlinuz-0-rescue-fe8e32bbb81547ccb85916d1fe2a32ff 50
root=UUID=1ef020e7-9a49-4a5d-ae32-fb03caef3f29 46
ro 2
crashkernel=auto 16
rhgb 4
quiet 5
[root@redhat7 rules.d]#awk '/^[[:space:]]*linux16/{i=1;while(i<=NF){if(length($i)>=10){print $i,length($i)};i++}}' /etc/grub2.cfg 
/vmlinuz-3.10.0-693.el7.x86_64 30
root=UUID=1ef020e7-9a49-4a5d-ae32-fb03caef3f29 46
crashkernel=auto 16
LANG=en_US.UTF-8 16
/vmlinuz-0-rescue-fe8e32bbb81547ccb85916d1fe2a32ff 50
root=UUID=1ef020e7-9a49-4a5d-ae32-fb03caef3f29 46
crashkernel=auto 16
[root@centos7 ~]#cat f1.txt
1 2 3 4 5 6 7 8 9 10
10 11 12 13 14 15 16 17 18 19 20
[root@centos7 ~]#awk '{i=1;sum=0;while(i<=NF){sum+=i;i++};print sum,i}' f1.txt         
55 11
66 12
[root@centos7 ~]#awk '{i=1;sum=0;while(i<=NF){sum+=$i;i++};print sum,i}' f1.txt  ---计算每一行的和,因为sum有初始值,所以每一行读
进来的时候sum刚开始都是0,从0开始往上加
55 11
165 12
[root@centos7 ~]#awk '{i=1;while(i<=NF){sum+=$i;i++}}END{print sum}' f1.txt   ---END是用于汇总,这里sum没有初始值,默认是0,当
第二行读进来的时候,sum的初始值是第一行的和,再整个基础上继
续相加                 
220
[root@centos7 ~]#awk '{i=1;while(i<=NF){sum+=$i;i++};print sum,i}END{print sum}' f1.txt    ---这个可以看的很清楚,当sum没有
在大括号里定义初始值时,第二行读进来时就是在第一行的基础上相加。
55 11
220 12
220
  • 计算1到100之和的方法总结:
方法一
[root@redhat7 system]#echo {1..100}|tr ' ' '+'|bc
5050
方法二
[root@redhat7 system]#seq -s "+" 100|bc
5050
方法三
[root@redhat7 system]#sum=0;for i in {1..100};do let sum+=i;done;echo $sum
5050
方法四
[root@redhat7 script]#i=1,sum=0;while [ $i -le 100 ];do let sum+=i;let i++;done;echo $sum
方法五
5050
[root@redhat7 script]#for((i=1,sum=0;i<=100;i++));do let sum+=i;done;echo $sum
5050
方法六
[root@redhat7 script]#awk 'BEGIN{sum=0;i=1;while(i<=100){sum+=i;i++};print sum}'
5050
  • for循环
    语法:for(expr1;expr2;expr3) {statement;…}
    常见用法:
    for(变量初始化;条件判断;变量的修正表达式)
    {for-body}
    特殊用法:能够遍历数组中的每一个元素
    语法:for(var in array)
    示例
[root@redhat7 script]#awk '/^[[:space:]]*linux16/{for(i=1;i<=NF;i++){print $i,length($i)}}' /etc/grub2.cfg 
  • 性能比较
[root@redhat7 script]#time (awk 'BEGIN{for(i=1;i<=100000;i++){sum+=i};print sum}')
5000050000

real    0m0.012s
user    0m0.010s
sys 0m0.002s
[root@redhat7 script]#time (sum=0;for i in {1..100000};do let sum+=i;done;echo $sum)
5000050000

real    0m0.521s
user    0m0.099s
sys 0m0.422s
[root@redhat7 script]#time (seq -s "+" 100000|bc)
5000050000

real    0m0.039s
user    0m0.040s
sys 0m0.003s

可以看出awk的运算速度是最快的

  • break和continue、next
[root@redhat7 script]#awk 'BEGIN{sum=0;for(i=1;i<=100;i++){if(i%2==0)continue;sum+=i};print sum}'
2500
[root@redhat7 script]#awk 'BEGIN{sum=0;for(i=1;i<=100;i++){if(i==66)break;sum+=i}print sum}'
2145
[root@redhat7 script]#awk 'BEGIN{sum=0;for(i=1;i<=100;i++){if(i==66)continue;sum+=i}print sum}'   
4984
[root@redhat7 script]#awk -F: '{if($3%2!=0)next;print $1,$3}' /etc/passwd
root 0
daemon 2
lp 4
shutdown 6
mail 8
games 12
ftp 14
systemd-network 192
sshd 74
zhang 1000
apache 48

总结:前两个和bash里面的用法相同,continue是跳出本轮循,break是跳出整个循环,next是提前结束对本行处理而直接进入下一行处理(awk自带行的循环)。

8、awk数组

awk的数组为关联数组,即索引下标为任意的字符串,不是数字表示索引。若要遍历数组中的每个元素,要使用for循环 for(var in array)
注意:var会遍历数组array的每个索引。
示例

[root@redhat7 app]#awk -F: '{line[$7]++}END{for(i in line){print i,line[i]}}' /etc/passwd
/bin/sync 1
/bin/bash 3
/sbin/nologin 16
/sbin/halt 1
/sbin/shutdown 1
表示第七列的值为数组line的索引下标,如果第七列的值有相同的,
数组line的值就加1,i会遍历数组line的每一个索引值,打印i就表示第
七列的值,line这个数组,因为没有赋值,所以刚开始的时候是0,当
有相同索引下标时,就加1,这样不断累加,line[i]就可以表示出重复
的索引值出现了多少次,重复一次,数组line就加1。
[root@redhat7 app]#netstat -nat|awk '/^tcp/{state[$NF]++}END{for(i in state){print i,state[i]}} '
LISTEN 5
ESTABLISHED 2
[root@redhat7 app]#cat f1
aaaaa
ddddd
ccccc
aaaaa
bbbbb
ccccc
ddddd
bbbbb
[root@redhat7 app]#awk '!line[$0]++' f1
aaaaa
ddddd
ccccc
bbbbb
       这种用法可以用于去掉重复的行,并且原来的次序不会打乱,比用sort和uniq好。
     解释说明:因为line这个数组没有赋值,所以刚开始的时候line这
个数组的值为0,把文件的每一行做为数组的索引值,如果没有遇到
相同的行时,line的数组值都是0,然后先取反,取反后为真,就打印
整行,然后加1,此时数组的值为1,这里省略了action,就会默认打
印整行,当有相同的行读进来时。line数组的值为1,取反就为假。不
打印,line数组的值加1,变为2,当有第三个相同的行时,因为line的
值不是0,所以每次取反,都为假,不会执行打印,利用这种方法就
可以去掉重复的行了。
    注意:!的优先级要比++的优先级高,先进行非判断是否打印,然后再++
[root@redhat7 app]#netstat -nt|awk -F "[[:space:]:]+" '/^tcp/{ip[$6]++}END{for(i in ip){print i,ip[i]}}'|sort -k2 -nr|head -n 10
-F "[[:space:]:]+" 表示以空格或者冒号做为分割符,这样可以用一次awk取出ip地址那行

9、awk函数

数值处理:
rand():返回0和1之间一个随机数

[root@redhat7 app]#awk 'BEGIN{print rand()}'
0.237788
[root@redhat7 app]#awk 'BEGIN{print rand()}'
0.237788
[root@redhat7 app]#awk 'BEGIN{print rand()}'
0.237788
[root@redhat7 app]#awk 'BEGIN{srand();print rand()}'
0.0522516    ---必须和srand()配合使用,才能显示0-1之前的随机
数,否则值不会改变,就像上面的一样,值不是随机数
[root@redhat7 app]#awk 'BEGIN{srand();print rand()*100}'
26.8591  ---乘以100后不是整数
[root@redhat7 app]#awk 'BEGIN{srand();print int(rand()*100)}'
[root@redhat7 app]#awk 'BEGIN{srand();for (i=1;i<=10;i++){print int(rand()*100)}}'   --可以打印10个随机数
22   ---可以用int声明是整数

字符串处理:
•length([s]):返回指定字符串的长度,小括号里面如果是字符串,要用双引号,如果是变量就不用了
•sub(r,s,[t]):对t字符串进行搜索,r表示模式匹配的内容,并将第一个匹配的内容替换为s

[root@redhat7 app]#echo "2008:08:08 08:08:08" | awk 'sub(/:/,"-",$1)'    ---因没有指定分割符,所以默认是空格做为分隔符,搜索第一列,将冒号替换为-号
2008-08:08 08:08:08

•gsub(r,s,[t]):对t字符串进行搜索,r表示模式匹配的内容,并全部替换为s所表示的内容

[root@redhat7 app]#echo "2008:08:08 08:08:08" | awk 'gsub(/:/,"-",$0)'
2008-08-08 08-08-08

•split(s,array,[r]):以r为分隔符,切割字符串s,并将切割后的结果保存至array所表示的数组中,第一个索引值为1,第二个索引值为2,…

[root@redhat7 app]#netstat -nt|awk '/^tcp\>/{split($5,ip,":");count[ip[1]]++}END{for(i in count){print i,count[i]}}'

解释:因为没有指定输入分割符,所以默认是空白字符,模式匹配,
匹配以tcp打头的行,以冒号做为分割符,切割第五列,将切割的结
果保存在ip这个数组中,并且切割的第一列的值保存在ip[1]这个索引
为1的数组元素中,然后将这个数组元素定义为count数组的索引值,
就可以利用这种方式去显示每个ip地址出现的次数。

  • 计算出男生和女生的总分数和平级成绩
[root@redhat7 app]#cat f1
mage 100 male
wang 90 male
zhang 80 female
li 100 female
[root@redhat7 app]#awk '{total[$3]+=$2;num[$3]++}END{for(name in total){print name,total[name],total[name]/num[name]}}' f1
[root@redhat7 app]#awk '{if($3 == "male"){msum+=$2;mnum++}else{fsum+=$2;fnum++}}END{printf "msum=%d  mavg=%.2f\nfsum=%d favg=%.2f\n",msum,msum/mnum,fsum,fsum/fnum}'  f1
  • 自定义函数
    格式:
    function name ( parameter, parameter, ... ) {
    statements
    return expression
    }
    示例:
#cat fun.awk
function max(v1,v2) {
v1>v2?var=v1:var=v2
return var
}
BEGIN{a=3;b=2;print max(a,b)}
#awk –f fun.awk

10、awk脚本

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

awk BEGIN'{system("hostname") }'
awk'BEGIN{score=100; system("echo your score is " score) }'

如何在ssh日志文件中找到外部主机ssh连接失败的ip地址的数目,如果连接失败的次数大于5次,就放到防火墙里禁止用ssh连接本主机。
方法一

[root@centos6 app]#vim awk.sh 
  1 #!/bin/bash
  2 #
  3 while true;do
  4 cat /var/log/secure|awk '/Failed/{ip[$(NF-3)]++}END{for(i in ip){if(ip[i]>=5){system("iptables -A INPUT -s "i" -j REJECT")}}}'
  5   sleep 5
  6  done

方法二

[root@centos6 app]#cat jianchassh.sh 
#!/bin/bash
#
while true;do
 cat /var/log/secure |grep "Failed"|awk '{ip[$(NF-3)]++}END{for(i in ip){print i,ip[i]}}'> /app/f6
cat /app/f6 |while read file;do
         ip=`echo $file|cut -d ' ' -f1`
         num=`echo $file|cut -d ' ' -f2`
         if [ $num -ge 5 ];then
               iptables -A INPUT -s $ip -j REJECT
          fi
           done
           sleep 2m
    done

awk脚本

#cat f1.awk
{if($3>=1000)print $1,$3}
#awk -F: -f f1.awk /etc/passwd
#cat f2.awk
#!/bin/awk –f   --要写awk的蛇棒机制
#this is a awkscript
{if($3>=1000)print $1,$3}
#chmod +x f2.awk
#f2.awk –F: /etc/passwd

向awk脚本传递参数

#cat test.awk
#!/bin/awk –f
{if($3 >=min && $3<=max)print $1,$3}
#chmod +x test.awk
#test.awk -F: min=100 max=200 /etc/passwd

你可能感兴趣的:(2018-05-06 GNU awk 2)