00x01 awk介绍
awk: Aho, Weinberger, Kernighan,报告生成器,格式化文本输出,用于在linux/unix下对文本和数据进行处理。数据可以来自标准输入、一个或多个文件,或其它命令的输出。它支持用户自定义函数和动态正则表达式等先进功能
有多种版本: New awk(nawk), GNU awk(gawk)
gawk:模式扫描和处理语言
00x02 awk基本用法
基本用法:
awk [options] ‘program’ var=value file…
awk [options] -f programfile var=value file…
awk [options] 'BEGIN{ action;… } pattern{ action;… } END{action;… }' file ...
awk 程序通常由: BEGIN语句块、能够使用模式匹配的通用语句块、 END语句块,共3部分组成
program通常是被单引号或双引号中
选项:
-F 指明输入时用到的字段分隔符
-v var=value: 自定义变量
基本格式:
awk [options] 'program' file…
program:pattern{action statements;..}
pattern和action:
pattern部分决定动作语句何时触发及触发事件
BEGIN,END
action statements对数据进行处理,放在{}内指明
print, printf
分割符、域和记录
awk执行时, 由分隔符分隔的字段(域)标记$1,$2..$n称为域标识。 $0为所有域,注意:和shell中变量$符含义不同
文件的每一行称为记录
省略action,则默认执行 print $0 的操作
00x03 awk工作原理
第一步:执行BEGIN{action;… }语句块中的语句
第二步:从文件或标准输入(stdin)读取一行,然后执行pattern{action;… }语句块,它逐行扫描文件,从第一行到最后一行重复这个过程,直到文件全部被读取完毕。
第三步:当读至输入流末尾时,执行END{action;…}语句块
BEGIN语句块在awk开始从输入流中读取行之前被执行,这是一个可选的语句块,比如变量初始化、打印输出表格的表头等语句通常可以写在BEGIN语句块中
END语句块在awk从输入流中读取完所有的行之后即被执行,比如打印所有行的分析结果这类信息汇总都是在END语句块中完成,它也是一个可选语句块
pattern语句块中的通用命令是最重要的部分,也是可选的。如果没有提供pattern语句块,则默认执行{ print },即打印每一个读取到的行, awk读取的每一行都会执行该语句块
00x04 print
print格式: print item1, item2, ...
要点:
(1) 逗号分隔符
(2) 输出的各item可以字符串,也可以是数值;当前记录的字段、
变量或awk的表达式
(3) 如省略item,相当于print $0
示例:
awk '{print "hello,awk"}'
awk �CF: '{print}' /etc/passwd
awk �CF: ‘{print “wang”}’ /etc/passwd
awk �CF: ‘{print $1}’ /etc/passwd
awk �CF: ‘{print $0}’ /etc/passwd
awk �CF: ‘{print $1”\t”$3}’ /etc/passwd
tail �C3 /etc/fstab |awk ‘{print $2,$4}’
00x05 变量
变量:常用内置变量
a、FS
FS field-separator 输入字段分隔符,默认为空白字符
使用FS的好处就是可以在内部调用这个变量
[root@localhost tmp]# awk -v FS=":" '{print $1,FS,$3}' passwdroot : 0
bin : 1
daemon : 2
adm : 3
lp : 4
sync : 5
[root@localhost tmp]# awk -F ":" '{print $1":"$3}' passwdroot:0bin:1daemon:2adm:3lp:4sync:5
b、OFS
output field-separator 输出字段分隔符,默认为空白字符
[root@localhost tmp]# awk -v FS=":" -v OFS="$" '{print $1,$3,$7}' passwdroot$0$/bin/bashbin$1$/sbin/nologindaemon$2$/sbin/nologinadm$3$/sbin/nologin
c、RS
输入记录分隔符,指定输入时的换行符,原换行符仍有效
[root@localhost tmp]# awk -v FS=":" -v OFS="$" '{print $1,$3,$7}' passwdnobody:x:99:99:Nobody:/:/sbin/nologinsystemd-bus-proxy:x:999:997:systemdBusProxy:/:/sbin/nologinsystemd-network:x:192:192:systemdNetwork
[root@localhost tmp]# cat testlist a b ddlist2 a2 b2 dd2list4 a3 b3 dd3[root@localhost tmp]# cat test |awk -v RS=" " -v OFS="++" '{print $1,$2}'list++ a++b++ dd++list2 #指定 RS“ ”,dd\nlist2,FS默认为空白字符,$1就是dda2++b2++dd2++list4a3++ b3++dd3++
d、 ORS
输出记录分隔符,输出时用指定符号代替换行符
[root@localhost tmp]# awk -v RS=" " -v ORS="%" '{print}' passwdroot:x:0:0:yemo,62985600:/root:/bin/bashbin:x:1:1:bin:/bin:/sbin/nologindaemon:x:2:2:daemon:/sbin:/sbin/nologinsystemd-bus-proxy:x:999:997:systemd%Bus%Proxy:/:/sbin/nologinsystemd-network:x:192:192:systemd%Network%Management:/:/sbin/nologindbus:x:81:81:System%message%bus:/:/sbin/nologinpolkitd:x:998:996:User%for%polkitd:/:/sbin/nologintss:x:59:59:Account%used%by%the%trousers%package%to%sandbox%the%tcsd%daemon:/dev/null:/sbin/nologin
e、 NF
字段数量
[root@localhost tmp]# cat passwd |awk -F: '{print NF}' #不需要使用$7777
可以用于循环每行每个字段
[root@localhost tmp]# cat passwd |awk -F: '{for(i=0;i<NF;i++){print $i}}'root:x:0:0:yemo,62985600:/root:/bin/bashrootx00yemo,62985600/rootbin:x:1:1:bin:/bin:/sbin/nologin
f、 NR
行号
[root@localhost tmp]# cat passwd |awk -F: '{print NR}'1234[root@localhost tmp]# awk 'END{print NR}' passwd22
e、 FNR
各文件分别计数,行号
[root@localhost tmp]# awk '{print FNR}' /etc/fstab /etc/inittab123456789101112131412...
f、 FILENAME
当前文件名
[root@localhost tmp]# awk '{print FILENAME}' /etc/fstab/etc/fstab/etc/fstab/etc/fstab/etc/fstab/etc/fstab/etc/fstab
g、 ARGC
命令行参数的个数
[root@localhost tmp]# awk 'END{print ARGC}' /etc/fstab /etc/inittab3
h、 ARGV
数组,保存的是命令行所给定的各参数
[root@localhost tmp]# awk 'END{print ARGV[1]}' /etc/fstab /etc/inittab/etc/fstab[root@localhost tmp]# awk 'END{print ARGV[0]}' /etc/fstab /etc/inittabawk[root@localhost tmp]# awk 'END{print ARGV[2]}' /etc/fstab /etc/inittab/etc/inittab
00x06 自定义变量和环境变量
自定义变量(区分字符大小写)
(1) -v var=value
(2) 在program中直接定义
[root@localhost tmp]# awk -v a="sh" 'BEGIN{print a}'sh
[root@localhost tmp]# cat awkscript{print script,$1,$2}[root@localhost tmp]# awk -F: -f awkscript script="awk" /etc/passwdawk root x #引用文件的变量,相当于已经定义,不用再-v声明awk bin xawk daemon xawk adm xawk lp xawk sync xawk shutdown xawk halt x
环境变量:
00x07 printf格式化输出
a、格式printf “FORMAT” , item1, item2, ...
(1) 必须指定FORMAT
(2) 不会自动换行,需要显式给出换行控制符, \n
(3) FORMAT中需要分别为后面每个item指定格式符
b、实例
printf '\n'$(tput setaf 2; tput setab 0; tput bold)'background color show'$(tput sgr0)'\n\n'
%s字符串,\t打印tab,\n回车,printf默认不会输出换行符
[root@localhost matrix]# echo "hello world"|awk '{printf "%s\t%s\n",$1,$2}'hello world
%d十进制
[root@localhost matrix]# echo "12580 124"|awk '{printf "%d\t%d\n",$1,$2}'12580 124
%o无符号八进制
[root@localhost matrix]# echo "12580 124"|awk '{printf "%o\t%o\n",$1,$2}'30444 174
%x十六进制
[root@localhost matrix]# echo "12580 124"|awk '{printf "%x\t%x\n",$1,$2}'3124 7c
[root@localhost matrix]# awk -F: '{printf "Username: %s,UID:%d\n",$1,$3}' /tmp/passwdUsername: root,UID:0Username: bin,UID:1Username: daemon,UID:2Username: adm,UID:3Username: lp,UID:4
00x08 操作符
算术操作符:
x+y, x-y, x*y, x/y, x^y, x%y
-x: 转换为负数
+x: 转换为数值
[root@localhost matrix]# awk 'BEGIN{print 2-4}'-2[root@localhost matrix]# awk 'BEGIN{print 2^3}'8[root@localhost matrix]# awk -v a=m 'BEGIN{print +a}'0[root@localhost matrix]# awk -v a=m 'BEGIN{print a}'m[root@localhost matrix]# awk -v a=5 'BEGIN{print -a}'-5
字符串拼接
[root@localhost matrix]# awk -v a="hello" -v b="Rie Kugimiya" 'BEGIN{print ab}'[root@localhost matrix]# awk -v a="hello" -v b="Rie Kugimiya" 'BEGIN{print a b}'helloRie Kugimiya
赋值操作符: =, +=, -=, *=, /=, %=, ^=,++, --
[root@localhost matrix]# awk 'BEGIN{b=10;print b}'10[root@localhost matrix]# awk -F: '{for(i=0;i<NF;i++){print i}}' /tmp/passwd01234560123456
比较操作 ==, !=, >, >=, <, <=
[root@localhost matrix]# cat /etc/passwd|awk -F: '{if($3>100){print $0}}'systemd-bus-proxy:x:999:997:systemd Bus Proxy:/:/sbin/nologinsystemd-network:x:192:192:systemd Network Management:/:/sbin/nologinpolkitd:x:998:996:User for polkitd:/:/sbin/nologinabrt:x:173:173::/etc/abrt:/sbin/nologinyemo:x:1000:1000::/home/yemo:/bin/bash
模式匹配 ~:左边是否和右边匹配包含
[root@localhost matrix]# cat /etc/passwd|awk -F: '{if($1 ~/.*oo.*/){print}}'root:x:0:0:yemo,62985600:/root:/bin/bash[root@localhost matrix]# cat /etc/passwd|awk -F: '{if($0 ~/.*oo.*/){print}}'root:x:0:0:yemo,62985600:/root:/bin/bashlp:x:4:7:lp:/var/spool/lpd:/sbin/nologinmail:x:8:12:mail:/var/spool/mail:/sbin/nologinoperator:x:11:0:operator:/root:/sbin/nologinpostfix:x:89:89::/var/spool/postfix:/sbin/nologin
!~:是否不匹配
[root@localhost matrix]# cat /etc/passwd|awk -F: '{if($0 !~/.*oo.*/){print}}'bin:x:1:1:bin:/bin:/sbin/nologindaemon:x:2:2:daemon:/sbin:/sbin/nologinadm:x:3:4:adm:/var/adm:/sbin/nologinsync:x:5:0:sync:/sbin:/bin/syncshutdown:x:6:0:shutdown:/sbin:/sbin/shutdownhalt:x:7:0:halt:/sbin:/sbin/haltgames:x:12:100:games:/usr/games:/sbin/nologinftp:x:14:50:FTP User:/var/ftp:/sbin/nologinnobody:x:99:99:Nobody:/:/sbin/nologinsystemd-bus-proxy:x:999:997:systemd Bus Proxy:/:/sbin/nologinsystemd-network:x:192:192:systemd Network Management:/:/sbin/nologindbus:x:81:81:System message bus:/:/sbin/nologin
逻辑操作符 与&&,或||,非!
[root@localhost matrix]# cat /etc/passwd|awk -F: '{if($0 !~/.*oo.*/ &&$3 >100 ){print}}'systemd-bus-proxy:x:999:997:systemd Bus Proxy:/:/sbin/nologinsystemd-network:x:192:192:systemd Network Management:/:/sbin/nologinpolkitd:x:998:996:User for polkitd:/:/sbin/nologinabrt:x:173:173::/etc/abrt:/sbin/nologinyemo:x:1000:1000::/home/yemo:/bin/bash[root@localhost matrix]# awk -F: '!($3>=500) {print $3}' /etc/passwd0123456
函数调用
自定义函数调用
[root@localhost matrix]# echo "11 22"|awk '{print "max=",max($1,$2)}function max(a,b){if(a>b){return a;}else{return b;}}'max= 22
内部函数调用
[root@localhost matrix]# echo "ad 12 22 dd"|awk 'split($0,a){for(i in a)printf a[i]}'ddad1222
条件表达式
三元表达式: selector?if-true-expression:if-false-expression
[root@localhost matrix]# awk -F: '{$3>=1000?usertype="Common User":usertype="Sysadmin or SysUser";printf "%15s:%-s\n",$1,usertype}' /etc/passwd root:Sysadmin or SysUser bin:Sysadmin or SysUser daemon:Sysadmin or SysUser adm:Sysadmin or SysUser lp:Sysadmin or SysUser sync:Sysadmin or SysUser shutdown:Sysadmin or SysUser halt:Sysadmin or SysUser mail:Sysadmin or SysUser operator:Sysadmin or SysUser games:Sysadmin or SysUser ftp:Sysadmin or SysUser nobody:Sysadmin or SysUsersystemd-bus-proxy:Sysadmin or SysUsersystemd-network:Sysadmin or SysUser dbus:Sysadmin or SysUser polkitd:Sysadmin or SysUser tss:Sysadmin or SysUser abrt:Sysadmin or SysUser postfix:Sysadmin or SysUser sshd:Sysadmin or SysUser yemo:Common User
[root@localhost matrix]# awk -F: '{$3>=1000?usertype="Common User":usertype="Sysadmin or SysUser";printf "%-15s:%-s\n",$1,usertype}' /etc/passwdroot :Sysadmin or SysUserbin :Sysadmin or SysUserdaemon :Sysadmin or SysUseradm :Sysadmin or SysUserlp :Sysadmin or SysUsersync :Sysadmin or SysUsershutdown :Sysadmin or SysUserhalt :Sysadmin or SysUsermail :Sysadmin or SysUser
00x09 PATTERN:根据pattern条件,过滤匹配的行,再做处理
(1)如果未指定:空模式,匹配每一行
[root@localhost tmp]# awk '{print $1}' testlistlist2list4
(2) /regular expression/:仅处理能够模式匹配到的行,需要用/ /括起来
[root@localhost tmp]# cat passwd |awk -F: '/^root\>/ {print }'root:x:0:0:yemo,62985600:/root:/bin/bash #支持位置铆钉和单词铆钉[root@localhost tmp]# cat passwd |awk -F: '/root/ {print }' #包含root的全都匹配root:x:0:0:yemo,62985600:/root:/bin/bashoperator:x:11:0:operator:/root:/sbin/nologin
(3) relational expression: 关系表达式,结果为“真”才会被处理
真:结果为非0值,非空字符串
假:结果为空字符串或0值
[root@localhost tmp]# cat passwd |awk -F: 'i=1;j=1{print i,j}' #i=1后默认有{print $0}root:x:0:0:yemo,62985600:/root:/bin/bash1 1bin:x:1:1:bin:/bin:/sbin/nologin1 1daemon:x:2:2:daemon:/sbin:/sbin/nologin1 1
[root@localhost tmp]# cat passwd |awk -F: '$3>500 {print }'systemd-bus-proxy:x:999:997:systemd Bus Proxy:/:/sbin/nologinpolkitd:x:998:996:User for polkitd:/:/sbin/nologinyemo:x:1000:1000::/home/yemo:/bin/bash
匹配finger空的行
[root@localhost tmp]# cat passwd |awk -F: '!$5 {print }'abrt:x:173:173::/etc/abrt:/sbin/nologinpostfix:x:89:89::/var/spool/postfix:/sbin/nologinyemo:x:1000:1000::/home/yemo:/bin/bash
匹配默认bash是/bin/bash的用户
[root@localhost tmp]# awk -F: '$NF=="/bin/bash"{print $1,$NF}' passwdroot /bin/bashyemo /bin/bash
匹配 bash结尾
[root@localhost tmp]# awk -F: '$NF ~/bash$/{print $1,$NF}' passwdroot /bin/bashyemo /bin/bash
(4) line ranges: 行范围
startline,endline: /pat1/,/pat2/ 不支持直接给出数字格式
[root@localhost tmp]# awk -F: '/^root\>/,/^mail\>/{print $1,$3}' passwdroot 0 #类似sed的用法bin 1daemon 2adm 3lp 4sync 5shutdown 6halt 7mail 8
[root@localhost tmp]# awk -F: '(NR>=3&&NR<=10){print $1,$3}' passwddaemon 2adm 3lp 4sync 5shutdown 6halt 7mail 8operator 11
(5) BEGIN/END模式
BEGIN{}: 仅在开始处理文件中的文本之前执行一次
END{}:仅在文本处理完成之后执行一次
[root@localhost tmp]# seq 10|awk ''[root@localhost tmp]# seq 10|awk '1'12345678910[root@localhost tmp]# seq 10|awk '{i=!i;print i}'1010101010[root@localhost tmp]# seq 10|awk '{i=!i}'[root@localhost tmp]# seq 10|awk 'i=0;i=!i'12345678910[root@localhost tmp]# seq 10|awk 'i=1;i=!i'12345678910[root@localhost tmp]# seq 10|awk -v i=1 'i=!i'246810[root@localhost tmp]# seq 10|awk '!(i=!i)'246810
00x0a action
00x0b 控制语句
1)if循环
if(condition){statement;…}[else statement]
[root@localhost tmp]# cat passwd |awk -F: '{if($3>500){print}}'systemd-bus-proxy:x:999:997:systemd Bus Proxy:/:/sbin/nologinpolkitd:x:998:996:User for polkitd:/:/sbin/nologinyemo:x:1000:1000::/home/yemo:/bin/bash
[root@localhost tmp]# cat passwd |awk -F: '{if($NF=="/bin/bash"){print}}'root:x:0:0:yemo,62985600:/root:/bin/bashyemo:x:1000:1000::/home/yemo:/bin/bash
[root@localhost tmp]# cat passwd |awk -F: '{if($5!=""){print}}'root:x:0:0:yemo,62985600:/root:/bin/bashbin:x:1:1:bin:/bin:/sbin/nologindaemon:x:2:2:daemon:/sbin:/sbin/nologinadm:x:3:4:adm:/var/adm:/sbin/nologin
[root@localhost tmp]# cat passwd |awk -F: '{if($3>500){printf "commusr:%s\n",$1}else{printf "sysuser:%s\n",$1 }}'sysuser:rootsysuser:binsysuser:daemonsysuser:admsysuser:gamessysuser:ftpsysuser:nobodycommusr:systemd-bus-proxysysuser:systemd-networksysuser:dbuscommusr:polkitdsysuser:tsssysuser:abrtsysuser:postfixsysuser:sshdcommusr:yemo
[root@localhost tmp]# df -P|awk -F "% " '/dev\/sd/ {print}'|awk '{if($5>3)printf "%s\t%s\n",$1,$5}'/dev/sda2 4%/dev/sda1 3%
if(condition1){statement1}else if(condition2){statement2}else{statement3}
[root@localhost tmp]# echo "10 99 100 60 50"|awk '{for(i=1;i<(NF+1);i++) {if($i>=90){print $i,"verygood";}else if($i>=60&&$i<90){print $i,"is ok";}else {print $i"you are too low"} }}'10you are too low99 verygood100 verygood60 is ok50you are too low
while循环
语法: while(condition){statement;…}
条件“真”,进入循环;条件“假”, 退出循环
使用场景:
对一行内的多个字段逐一类似处理时使用
对数组中的各元素逐一处理时使用
[root@localhost tmp]# awk '/^\s*linux16/{i=1;while(i<=NF){print $i,length($i);i++}}' /etc/grub2.cfglinux16 7/vmlinuz-3.10.0-514.el7.x86_64 30root=UUID=cb8a4d4d-51c6-417f-a8d8-fc8948450fcd 46ro 2crashkernel=auto 16rhgb 4quiet 5LANG=en_US.UTF-8 16net.ifnames=0 13
[root@localhost tmp]# awk '/^\s*linux16/{i=1;while(i<=NF){if(length($i)>10){print $i,length($i)};i++ } }' /etc/grub2.cfg/vmlinuz-3.10.0-514.el7.x86_64 30root=UUID=cb8a4d4d-51c6-417f-a8d8-fc8948450fcd 46crashkernel=auto 16LANG=en_US.UTF-8 16net.ifnames=0 13/vmlinuz-0-rescue-8665dcc4833c41eaa11fa716f7dcd792 50root=UUID=cb8a4d4d-51c6-417f-a8d8-fc8948450fcd 46crashkernel=auto 16
do-while循环
语法: do {statement;…}while(condition)
意义:无论真假,至少执行一次循环体
[root@localhost tmp]# awk 'BEGIN{total=0;i=0;do{total+=i;i++;}while(i<=100);print total}'5050[root@localhost tmp]# awk 'BEGIN{total=1;i=1;do{total+=i;i++;}while(i<=0);print total}'2
[root@localhost tmp]# awk 'BEGIN{i=0;print ++i,i}' #先加后赋值1 1[root@localhost tmp]# awk 'BEGIN{i=0;print i++,i}' #先赋值在加0 1
for循环
语法:for(expr1;expr2;expr3) {statement;…}
常见用法:
for(variable assignment;condition;iteration process){for-body}
特殊用法:能够遍历数组中的元素
echo "10 99 100 60 50"|awk '{for(i=1;i<(NF+1);i++) {if($i>=90){print $i,"verygood";}else if($i>=60&&$i<90){print $i,"is ok";}else {print $i"you are too low"} }}'10you are too low99 verygood100 verygood60 is ok50you are too low
[root@localhost tmp]# cat access.log |awk '{++arr[$1]}{for(i in arr){print i,arr[i]}}'192.168.1.44 34172.16.100.76 204192.168.1.100 12192.168.1.101 1192.168.1.110 83192.168.99.72 18172.16.100.125 18127.0.0.1 7192.168.1.121 13192.168.1.112 27172.16.0.100 4172.16.100.126 3192.168.1.113 583172.16.23.100 14192.168.1.114 12192.168.6.1 42172.16.250.227 68192.168.1.106 22172.16.233.133 112192.168.1.107 68192.168.1.108 3
switch语句
语法: switch(expression) {case VALUE1 or /REGEXP/:statement1; case VALUE2 or /REGEXP2/: statement2;...; default: statementn}
break和continue
[root@localhost ~]# awk 'BEGIN{sum=0;for(i=0;i<=100;i++){if(i%2==0)continue;sum+=i}print sum }'2500
[root@localhost ~]# awk 'BEGIN{sum=0;for(i=0;i<=100;i++){if(i==55)break;sum+=i}print sum }'1485
[root@localhost ~]# awk -F: '{if($3%2!=0)next;print $1,$3}' /tmp/passwdroot 0daemon 2lp 4shutdown 6mail 8games 12ftp 14systemd-network 192polkitd 998sshd 74yemo 1000
00x0b awk数组
a) 关联数组: array[index-expression]
index-expression:
(1) 可使用任意字符串;字符串要使用双引号括起来
(2) 如果某数组元素事先不存在,在引用时, awk会自动创建此元素,并将其值初始化为“空串”
若要判断数组中是否存在某元素,要使用“index in array”格式进行遍历
若要遍历数组中的每个元素,要使用for循环
for(var in array) {for-body}
注意: var会遍历array的每个索引
[root@localhost tmp]# cat access.log |awk '{++arr[$1]}{for(i in arr){print i,arr[i]}}'192.168.1.44 34172.16.100.76 204192.168.1.100 12192.168.1.101 1192.168.1.110 83192.168.99.72 18172.16.100.125 18127.0.0.1 7192.168.1.121 13192.168.1.112 27172.16.0.100 4172.16.100.126 3192.168.1.113 583172.16.23.100 14192.168.1.114 12192.168.6.1 42172.16.250.227 68192.168.1.106 22172.16.233.133 112192.168.1.107 68192.168.1.108 3
使用关联数组对重复IP地址计数,以IP地址为索引,出现相同索引的就自加,达到计数的目的,数组缺省值为0。
00x0c 函数
a)内置函数
01 sub函数匹配记录中最大、最靠左边的子字符串的正则表达式,并用替换字符串替换这些字符串。如果没有指定目标字符串就默认使用整个记录。替换只发生在第一次匹配的时候。
sub (regular expression, substitution string):
sub (regular expression, substitution string, target string)
[root@localhost tmp]# awk '{sub(/a/,"test");print}' testlisttest a ba dadlisttest2 a2 ba2 dad2listtest4 a3 ba3 dad3[root@localhost tmp]# cat testlista a ba dadlista2 a2 ba2 dad2lista4 a3 ba3 dad3
02 gsub函数作用如sub,但它在整个文档中进行匹配。
[root@localhost tmp]# awk '{gsub(/a/,"test");print}' testlisttest test btest dtestdlisttest2 test2 btest2 dtestd2listtest4 test3 btest3 dtestd3
03 index 函数返回子字符串第一次被匹配的位置,偏移量从位置1开始。
index(string, substring)
04 substr函数返回从位置1开始的子字符串,如果指定长度超过实际长度,就返回整个字符串。
substr( string, starting position )
substr( string, starting position, length of string )
05 split函数可按给定的分隔符把字符串分割为一个数组。如果分隔符没提供,则按当前FS值进行分割。
split( string, array, field separator )
split( string, array )
06 length函数返回记录的字符数。
length( string )
length
07 match函数返回在字符串中正则表达式位置的索引,如果找不到指定的正则表达式则返回0。match函数会设置内建变量RSTART为字符串中子字符串的开始位置,RLENGTH为到子字符串末尾的字符个数。substr可利于这些变量来截取字符串。
match( string, regular expression )
08 toupper和tolower函数可用于字符串大小间的转换,该功能只在gawk中有效。
toupper( string )
tolower( string )
b) 数学函数
00x0d 通过system调用系统命令
空格是awk中的字符串连接符,如果system中需要使用awk中的变量可以使用空格分隔,或者说除了awk的变量外其他一律用""引用起来。
[root@localhost ~]# awk 'BEGIN{system("hostname")}'localhost.localdomain[root@localhost ~]# awk 'BEGIN{s=100;system("echo your score is" s)}'your score is100[root@localhost ~]# awk 'BEGIN{s=100;system("echo your score is " s)}'your score is 100
00x0e 创建awk脚本
[root@localhost tmp]# vim tstawk.awk[root@localhost tmp]# cat tstawk.awk#!/bin/awk -f{if($3>=1000)print $1,$3}[root@localhost tmp]# awk -F: -f tstawk.awk passwdyemo 1000
[root@localhost tmp]# chmod +x tst2.awk[root@localhost tmp]# cat tst2.awk#!/bin/awk -f{if($3>=1000)print $1,$3}[root@localhost tmp]# ./tst2.awk -F: passwdyemo 1000
向awk脚本传递参数
格式:
awkfile var=value var2=value2... Inputfile
注意:在BEGIN过程中不可用。直到首行输入完成以后,变量才可用。可以通过-v 参数,让awk在执行BEGIN之前得到变量的值。命令行中每一个指定的变量都需要一个-v参数
[root@localhost tmp]# cat tst2.awk#!/bin/awk -f{if($3>=min && $3<=max)print $1,$3}[root@localhost tmp]# ./tst2.awk -F: min=100 max=500 passwdsystemd-network 192abrt 173
实例:
对fstab文件取单词并计数排序
[root@localhost tmp]# cat /etc/fstab |tr "[:punct:]" " " |awk '{split($0,arr," ");for(i in arr){brr[arr[i]]++ }} END{for(k in brr){print brr[k],k}} '|sort -nr6 UUID6 defaults5 xfs3 82 swap2 fstab2 by1 Wed1 var1 under1 See1 reference1 pages
提取字符串中数字
[root@localhost tmp]# echo "Yd$C@M05MB%9&Bdh7dq+YVixp3vpw"|awk -F "[^[:digit:]]" '{for(i=1;i<=NF;i++){printf "%s",$i}}'05973
[root@localhost tmp]# ss -ntl|awk -F "[ :]" '/^[^S]/ {arr[$6]++}END{for(i in arr){print arr[$i],i}}'|sort -nr
去掉一个最高一个最低求平均值
冯泉 100 100 96 95 100 96 100 97万永振 100 95 90 88 95 98 95 98徐亮�� 100 100 90 98 90 98 100 96曹雅楠 100 100 95 90 97 90 95 98陈派宇 90 95 95 96 100 98 100 96李峰 90 90 90 85 92 95 95 98余连辉 90 93 95 92 95 95 96 95侯亚光 90 96 97 90 90 85 95 90王续 85 92 98 98 90 95蔚雷 92 92 96 90 90 80苏浩智 88 96 85 95 90 90徐登辉 85 95 88 90 90 90林章益 91 97 98 90 100 90黄品清 85 97 88 90 90 90李健 85 95 90 88 80 80宫全乐 88 95 90 88 90 100万良 89 95 95 88 100 100马自强 88 97 90 88 90 90任冠亚 88 97 98 90 100 100
解法1
[root@localhost tmp]# cat awk_tst.tst |awk '{for(i=2;i<=NF;i++){a[i]=$i};sum=0;tmp=0;for(j in a){for(k in a){if(a[k]>a[j]){tmp=a[k];a[k]=a[j];a[j]=tmp;}}}for(s=2;s<length(a);s++){sum+=a[s]};arr=sum/(length(a)-2);print $1,arr;delete a}'
本文出自 “庭前夜末空看雪” 博客,请务必保留此出处http://12550795.blog.51cto.com/12540795/1966558