当前位置: 首页 > Linux

AWK介绍

时间:2023-04-06 21:11:54 Linux

1:介绍如何显示文本内容,不是修改文件,而是逐行读取文件格式:awk[options]'program'fileoption选项:-F表示字段输入时使用的分隔符-vvar=value自定义变量程序模式:pattern{action.....}pattern:匹配对应行,不标则匹配整个文件action:匹配到匹配行时要做的动作.常用于打印printprintf(使用此选项进行更复杂的打印)eg:awk–F:'{print$1,$2}'/etc/passwdawk-F:'{print$1"\t\t\t"$5}'/etc/passwd"t"表示tab键awk-F:'{printf$1"\t\t\t"$5"n"}'/etc/passwdprintf打印默认不支持换行,需要加n要牢记:printf打印内容时,变量不加“”。二:awk变量(内置):多练习可以熟练使用配合-vuseFS:输入字段分隔符,默认为空白字符awk-vFS=':''{print$1,FS,$3}'/etc/passwdOFS:输出字段分隔符,默认为空白字符RS:输入记录分隔符,输入时指定换行符,原换行符仍然有效ORS:输出记录分隔符,输入时用指定符号替换换行符输出NF:字段号NR:行号FNR:每个文件单独统计,行号FILENAME:当前文件名ARGC:命令行参数个数ARGV:数组,保存命令行给定的参数下面是示例变量的使用:在bash中定义的变量也可以直接在awd中使用1)FSOFS使用示例2)RSORS记录分隔符NR行号FNR每个文件统计NF分隔的字段数,这个变量可以用在数组NF和$的结合$NF更好用打印还支持数值计算3)FILENAME:当前文件名ARGC:命令行参数个数,,,其中'program'不是awk的参数,最后一个文件是一个参数,如下例可见这一段三:awk变量(自定义):1)-vvar=value2)直接在程序中定义外部和内部定义就可以了示例:awk-vtest='hellogawk''{printtest}'/etc/fstabawk-vtest='hellogawk''BEGIN{printtest}'awk'BEGIN{test="hello,gawk";printtest}'awk–F:'{sex="male";print$1,sex,age;age=18}'/etc/passwd四:printf在printf中不加""字符串,printf默认识别为变量,不换行默认情况下。如果要换行,添加n1:格式匹配格式:格式用""原因%c:显示字符%d的ASCII码,:显示十进制整数%f:显示为浮点数%s:显示字符串%%:显示%self修饰符:(#.#)第一个数字控制显示第二个#表示小数点后的精度,%3.1f-:左对齐(默认右对齐)%-15s,,15表示宽度+:显示值的正负号%+d修饰符一般写在格式的中间,为了进一步描述格式格式,修饰符用于修饰后面的变量打印的格式应用示例:1)合成使用格式%s%dn个字符宽度左对齐宽度为25个字符2)添加字符串显示2:运算符:算术运算符:x+y、x-y、x*y、x/y、x^y,x%y-x:转为负数+x:转为数值赋值运算符:=,+=,-=,*=,/=,%=,^=++,--比较运算符:==,!=,>,>=,<,<=逻辑运算符:and&&,or||,not!例子:awk–F:'$3>=0&&$3<=1000{print$1}'/etc/passwd·awk-F:'$3==0||$3>=1000{print$1}'/etc/passwd·awk-F:'!($3==0){print$1}'/etc/passwd?awk-F:'!($3>=500){print$3}'/etc/passwd3:patternmatchingcharacter:这块极其重要,毕竟是正则化的熟练使用~:左边是否匹配右边包含!~:不匹配匹配的内容使用""或//frameawk–F:'$0~/root/{print$1}'/etc/passwdawk'$0~"^root"'/etc/passwdawk'$0!~/root/'/etc/passwdawk–F:'$3==0'/etc/passwd应用例子:awk-F:'$0~/root/{printf$0"n"}'/etc/passwd正则表达式写法:awk-F:'$0~/^root/{printf$0"n"}'/etc/passwd模式匹配和运算符综合使用:awk-F:'$3>=500{printf$0"n"}'/etc/passwdawk-F:'$3>=500&&$3<=1000{printf"%-25s%-20dn",$1,$3}'当/etc/passwd逻辑不是时,要加上下面的比较运算符()awk-F:'!($3>=500){printf"%-25s%-20d\n",$1,$3}'/etc/passwd4:条件表达式(三元表达式):selector?if-true-expression:if-false-expression4:PATTERNawkformat:awkoption'pattern{action}'filePATTERN:根据pattern条件,过滤匹配的行再处理,不匹配的不处理lines1如果不指定:空pattern,匹配每一行2/regularexpression/:只处理能匹配pattern的行,需要用//awk'/^UUID/{print$1}'/etc/括起来fstabprintstartswithUUIDThelinefirstfieldofthelineawk'!/^UUID/{print$1}'/etc/fstab打印不以UUID开头的行的第一个字段打印partitionutilization3关系表达式:relationalexpression,结果为“True”会被处理True:结果为非零值,非空字符串False:结果为空字符串或0值0且无内容视为0值awk-F:-vn=0'n++{printf"%-25s%sn",$1,$5}'/etc/passwd这个例子很有意思,因为awk是逐行处理的,所以这个输出的结果就是第一个行没有输出,后面几行有输出。注:多次使用print打印,在中间添加;不显示/etc/passwd中以/bin/bash结尾的行1)awk-F:'$NF!="/bin/bash"'/etc/passwd2)这种写法使用~匹配符号awk-F:'$NF!~/bash$/'/etc/passwd4lineranges:linerangestartline,endline:/pat1/,/pat2/不支持直接给出数字格式,一找到part1就开始将匹配打印到part2结束此循环,再次找到part1,开始打印,找到pqrt2并结束......例如:awk'/^r/,/^h/'/etc/passwd匹配开头的行withrandstartingwithhawk'NR>=10&&NR<=20{printNR,$0}'/etc/passwdprintline10toline205BEGINEND首尾打印,与其他无关awk-F:'开始{print"usernameuid"}NR>=10&&NR<=20{printf"%-20s%-10sn",$1,$3}'/etc/passwdplusheaderawk-F:'BEGIN{print"usernameuidn------------------------------"}NR>=10&&NR<=20{printf"%-20s%-10sn",$1,$3}END{print"--------------------------------"}'/etc/passwd添加列:awk-F:'BEGIN{print"用户名uidn----------------------------"}NR>=10&&NR<=20{printf"%-20s|%-10sn",$1,$3}END{print"-----------------------------"}'六:常用控制语句:action1)算术运算,比较表达式2)控制语句,ifwhilefor3)打印常用控制语句:1){statement;.......}2)if(条件判断){command}3)if(条件判断){command}else{command}4)while(条件){command}5)for(1,2,3){command}6)breakcontinue1ifelse使用示例格式:if(condition){statement;…}[elsestatement]if(condition1){statement1}elseif(condition2){statement2}else{statement3}示例/ets/fstab一行字段数为morethan5print2whileloopawk中内置的循环,while用于行中的循环处理例子:1)取出每个单词并输出其长度awk-F:'{i=1;while(i<=NF){print$i,length($i);i++}}'/etc/passwd2)扎根行,并输出它的长度,以及每个单词awk-F:'/^root/{i=1;while(i<=NF){print$i,length($i);i++}}'/etc/passwd3)取出root开头的行,输出每个单词,单词长度必须大于5个字母awk-F:'/^root/{i=1;while(i<=NF){if(length($i)>=4)print$i,length($i);i++}}'/etc/passwd3for循环格式:for(1,2,3){4}特殊用法是:遍历数组中的元素,按照介绍4break,continue使用break打断循环;continue,跳出本次循环,进行下一次循环七:AWK数组awk使用的数组是关联数组awk经常使用for循环遍历数组中的元素例:1重复行不要打印awk'!arr[$0]++'f1在这条语句中,先进行逆运算,然后执行++命令,然后打印,最后将12加到arr[$0])中使用for循环遍历数组格式:for(varinarr){action}var会遍历arr数组的每个索引遍历ss–nat连接状态次数ss-nat|awk'!/^State/{arr[$1]++}END{for(iinarr){printi,arr[i]}}'arr[$1]++:$1表示第一个字段,++表示第一个字段相同时加1。for(iinarr):i遍历数组底部的arr下标,并将下标的值赋值给变量i另外,这一块还有一个重要的地方就是语法书写的格式。这就是多写多练。熟练之后,错误就会越来越少。ss-nat|awk'!/^State/{arr[$1]++}END{for(iinarr){printi,arr[i]}}'八:函数1数值处理rand():return0一个1到1之间的随机数,但是用srand的格式:srand()相当于一个种子,先调用srand()rand()生效eg:1:generatearandomnumberbetween0-1awk'BEGIN{printsrand(),rand()}'2:生成一个1-100之间的随机整数awk'BEGIN{srand();printint(rand()*100)}'int可以定义输出为整数3:生成10个1-100之间的随机整数awk'BEGIN{srand();for(i=0;i<=10;i++){printint(rand()*100)}}'2字符串处理1:length([s]):返回指定字符串的长度2:sub(r,s,[t]):搜索t字符串r匹配的内容指示的模式,将字符串中第一个匹配到的内容替换为seg:用-替换注意添加//echo"ac:d:e:f:g"|awk'sub(/:/,"-",$0)'echo"a:b:c:d:e:f:g"|gawk'sub(/:/,"-",$0)'3gsub(r,s,[t]):在字符串t上搜索r代表的模式匹配内容,全部替换为s指示的内容在全球范围内被替换。例子在2.4split(s,array,[r]):以r为分隔符,对字符串s进行切割,将切割结果保存到array表示的数组中,第一个索引值为1,第二个索引值为2,...eg:统计外部ip地址在netstat-antnetstat-ant|awk'/^tcp>/{split($5,arr,":")中出现的次数;count[arr[1]]++}END{for(iincount){printi,count[i]}}'3自定义函数格式:函数名(parameter,parameter,...){statementsreturnexpression}eg:#catfun.awkfunctionmax(v1,v2){v1>v2?var=v1:var=v2returnvar}BEGIN{a=3;b=2;printmax(a,b)}$awk-ffak。awk9:awk调用shell中的命令1使用系统命令2除了awk中定义的变量外,其他的都用""括起来eg:awk'BEGIN{system("hostname")}'awk'BEGIN{分数=100;system("echoyourscoreis"score)}'10:Example1averageawk-F'''{sum+=$1}END{printsum/NR}'a.txt