标签: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
原文地址:http://12187655.blog.51cto.com/12177655/1974017