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