首页 > 系统相关 >linux 文本分析工具---awk命令

linux 文本分析工具---awk命令

时间:2023-05-31 19:57:31浏览次数:41  
标签:%- passwd --- etc awk linux print root

awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大。简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理。

awk有3个不同版本: awk、nawk和gawk,未作特别说明,一般指gawk,gawk 是 AWK 的 GNU 版本。

awk其名称得自于它的创始人 Alfred Aho 、Peter Weinberger 和 Brian Kernighan 姓氏的首个字母。实际上 AWK 的确拥有自己的语言: AWK 程序设计语言 , 三位创建者已将它正式定义为“样式扫描和处理语言”。它允许您创建简短的程序,这些程序读取输入文件、为数据排序、处理数据、对输入执行计算以及生成报 表,还有无数其他的功能。

awk '{pattern + action}' {filenames}

尽管操作可能会很复杂,但语法总是这样,其中 pattern 表示 AWK 在数据中查找的内容,而 action 是在找到匹配内容时所执行的一系列命令。花括号({})不需要在程序中始终出现,但它们用于根据特定的模式对一系列指令进行分组。 pattern就是要表示的正则表达式,用斜杠括起来。

awk语言的最基本功能是在文件或者字符串中基于指定规则浏览和抽取信息,awk抽取信息后,才能进行其他文本操作。完整的awk脚本通常用来格式化文本文件中的信息。

通常,awk是以文件的一行为处理单位的。awk每接收文件的一行,然后执行相应的命令,来处理文本。

awk是行处理器: 相比较屏幕处理的优点,在处理庞大文件时不会出现内存溢出或是处理缓慢的问题,通常用来格式化文本信息 awk处理过程: 依次对每一行进行处理,然后输出
1.命令行方式
awk [-F  field-separator]  'commands'  input-file(s)
其中,commands 是真正awk命令,[-F域分隔符]是可选的。 input-file(s) 是待处理的文件。
在awk中,文件的每一行中,由域分隔符分开的每一项称为一个域。通常,在不指名-F域分隔符的情况下,默认的域分隔符是空格。

2.shell脚本方式
将所有的awk命令插入一个文件,并使awk程序可执行,然后awk命令解释器作为脚本的首行,一遍通过键入脚本名称来调用。
相当于shell脚本首行的:#!/bin/sh
可以换成:#!/bin/awk

3.将所有的awk命令插入一个单独文件,然后调用:
awk -f awk-script-file input-file(s)
其中,-f选项加载awk-script-file中的awk脚本,input-file(s)跟上面的是一样的
awk命令形式: awk [-F|-f|-v] ‘BEGIN{} //{command1; command2} END{}’ file  [-F|-f|-v]   大参数,-F指定分隔符,-f调用脚本,-v定义变量 var=value '  '          引用代码块 BEGIN   初始化代码块,在对每一行进行处理之前,初始化代码,主要是引用全局变量,设置FS分隔符 //           匹配代码块,可以是字符串或正则表达式 {}           命令代码块,包含一条或多条命令 ;          多条命令使用分号分隔 END      结尾代码块,在对每一行进行处理之后再执行的代码块,主要是进行最终计算或输出结尾摘要信息   特殊要点: $0           表示整个当前行 $1           每行第一个字段 NF          字段数量变量 NR          每行的记录号,多文件记录递增 FNR        与NR类似,不过多文件记录不递增,每个文件都从1开始 \t            制表符 \n           换行符 FS          BEGIN时定义分隔符 RS       输入的记录分隔符, 默认为换行符(即文本是按一行一行输入) ~            匹配,与==相比不是精确比较 !~           不匹配,不精确比较 ==         等于,必须全部相等,精确比较 !=           不等于,精确比较 &&      逻辑与 ||             逻辑或 +            匹配时表示1个或1个以上 /[0-9][0-9]+/   两个或两个以上数字 /[0-9][0-9]*/    一个或一个以上数字 FILENAME 文件名 OFS      输出字段分隔符, 默认也是空格,可以改为制表符等 ORS        输出的记录分隔符,默认为换行符,即处理结果也是一行一行输出到屏幕 -F'[:#/]'   定义三个分隔符   print & $0 print 是awk打印指定内容的主要命令 awk '{print}'  /etc/passwd   ==   awk '{print $0}'  /etc/passwd   awk '{print " "}' /etc/passwd                                           //不输出passwd的内容,而是输出相同个数的空行,进一步解释了awk是一行一行处理文本 awk '{print "a"}'   /etc/passwd                                        //输出相同个数的a行,一行只有一个a字母 awk -F":" '{print $1}'  /etc/passwd  awk -F: '{print $1; print $2}'   /etc/passwd                   //将每一行的前二个字段,分行输出,进一步理解一行一行处理文本 awk  -F: '{print $1,$3,$6}' OFS="\t" /etc/passwd        //输出字段1,3,6,以制表符作为分隔符   -f指定脚本文件 awk -f script.awk  file BEGIN{ FS=":" } {print $1}               //效果与awk -F":" '{print $1}'相同,只是分隔符使用FS在代码自身中指定   awk 'BEGIN{X=0} /^$/{ X+=1 } END{print "I find",X,"blank lines."}' test  I find 4 blank lines.  ls -l|awk 'BEGIN{sum=0} !/^d/{sum+=$5} END{print "total size is",sum}'                    //计算文件大小 total size is 17487   -F指定分隔符 $1 指指定分隔符后,第一个字段,$3第三个字段, \t是制表符 一个或多个连续的空格或制表符看做一个定界符,即多个空格看做一个空格 awk -F":" '{print $1}'  /etc/passwd awk -F":" '{print $1 $3}'  /etc/passwd                       //$1与$3相连输出,不分隔 awk -F":" '{print $1,$3}'  /etc/passwd                       //多了一个逗号,$1与$3使用空格分隔 awk -F":" '{print $1 " " $3}'  /etc/passwd                  //$1与$3之间手动添加空格分隔 awk -F":" '{print "Username:" $1 "\t\t Uid:" $3 }' /etc/passwd       //自定义输出   awk -F: '{print NF}' /etc/passwd                                //显示每行有多少字段 awk -F: '{print $NF}' /etc/passwd                              //将每行第NF个字段的值打印出来  awk -F: 'NF==4 {print }' /etc/passwd                       //显示只有4个字段的行 awk -F: 'NF>2{print $0}' /etc/passwd                       //显示每行字段数量大于2的行 awk '{print NR,$0}' /etc/passwd                                 //输出每行的行号 awk -F: '{print NR,NF,$NF,"\t",$0}' /etc/passwd      //依次打印行号,字段数,最后字段值,制表符,每行内容 awk -F: 'NR==5{print}'  /etc/passwd                         //显示第5行 awk -F: 'NR==5 || NR==6{print}'  /etc/passwd       //显示第5行和第6行 route -n|awk 'NR!=1{print}'                                       //不显示第一行   //匹配代码块 //纯字符匹配   !//纯字符不匹配   ~//字段值匹配    !~//字段值不匹配   ~/a1|a2/字段值匹配a1或a2    awk '/mysql/' /etc/passwd awk '/mysql/{print }' /etc/passwd awk '/mysql/{print $0}' /etc/passwd                   //三条指令结果一样 awk '!/mysql/{print $0}' /etc/passwd                  //输出不匹配mysql的行 awk '/mysql|mail/{print}' /etc/passwd awk '!/mysql|mail/{print}' /etc/passwd awk -F: '/mail/,/mysql/{print}' /etc/passwd         //区间匹配 awk '/[2][7][7]*/{print $0}' /etc/passwd               //匹配包含27为数字开头的行,如27,277,2777... awk -F: '$1~/mail/{print $1}' /etc/passwd           //$1匹配指定内容才显示 awk -F: '{if($1~/mail/) print $1}' /etc/passwd     //与上面相同 awk -F: '$1!~/mail/{print $1}' /etc/passwd          //不匹配 awk -F: '$1!~/mail|mysql/{print $1}' /etc/passwd           IF语句 必须用在{}中,且比较内容用()扩起来 awk -F: '{if($1~/mail/) print $1}' /etc/passwd                                       //简写 awk -F: '{if($1~/mail/) {print $1}}'  /etc/passwd                                   //全写 awk -F: '{if($1~/mail/) {print $1} else {print $2}}' /etc/passwd            //if...else...     条件表达式 ==   !=   >   >=   awk -F":" '$1=="mysql"{print $3}' /etc/passwd   awk -F":" '{if($1=="mysql") print $3}' /etc/passwd          //与上面相同  awk -F":" '$1!="mysql"{print $3}' /etc/passwd                 //不等于 awk -F":" '$3>1000{print $3}' /etc/passwd                      //大于 awk -F":" '$3>=100{print $3}' /etc/passwd                     //大于等于 awk -F":" '$3<1{print $3}' /etc/passwd                            //小于 awk -F":" '$3<=1{print $3}' /etc/passwd                         //小于等于   逻辑运算符 && ||  awk -F: '$1~/mail/ && $3>8 {print }' /etc/passwd         //逻辑与,$1匹配mail,并且$3>8 awk -F: '{if($1~/mail/ && $3>8) print }' /etc/passwd awk -F: '$1~/mail/ || $3>1000 {print }' /etc/passwd       //逻辑或 awk -F: '{if($1~/mail/ || $3>1000) print }' /etc/passwd    数值运算 awk -F: '$3 > 100' /etc/passwd     awk -F: '$3 > 100 || $3 < 5' /etc/passwd   awk -F: '$3+$4 > 200' /etc/passwd awk -F: '/mysql|mail/{print $3+10}' /etc/passwd                    //第三个字段加10打印  awk -F: '/mysql/{print $3-$4}' /etc/passwd                             //减法 awk -F: '/mysql/{print $3*$4}' /etc/passwd                             //求乘积 awk '/MemFree/{print $2/1024}' /proc/meminfo                  //除法 awk '/MemFree/{print int($2/1024)}' /proc/meminfo           //取整   输出分隔符OFS awk '$6 ~ /FIN/ || NR==1 {print NR,$4,$5,$6}' OFS="\t" netstat.txt awk '$6 ~ /WAIT/ || NR==1 {print NR,$4,$5,$6}' OFS="\t" netstat.txt         //输出字段6匹配WAIT的行,其中输出每行行号,字段4,5,6,并使用制表符分割字段   输出处理结果到文件 ①在命令代码块中直接输出    route -n|awk 'NR!=1{print > "./fs"}'    ②使用重定向进行输出           route -n|awk 'NR!=1{print}'  > ./fs   格式化输出 netstat -anp|awk '{printf "%-8s %-8s %-10s\n",$1,$2,$3}'  printf表示格式输出 %格式化输出分隔符 -8长度为8个字符 s表示字符串类型 打印每行前三个字段,指定第一个字段输出字符串类型(长度为8),第二个字段输出字符串类型(长度为8), 第三个字段输出字符串类型(长度为10) netstat -anp|awk '$6=="LISTEN" || NR==1 {printf "%-10s %-10s %-10s \n",$1,$2,$3}' netstat -anp|awk '$6=="LISTEN" || NR==1 {printf "%-3s %-10s %-10s %-10s \n",NR,$1,$2,$3}'   IF语句 awk -F: '{if($3>100) print "large"; else print "small"}' /etc/passwd   small awk -F: 'BEGIN{A=0;B=0} {if($3>100) {A++; print "large"} else {B++; print "small"}} END{print A,"\t",B}' /etc/passwd                                                                                                                    //ID大于100,A加1,否则B加1 awk -F: '{if($3<100) next; else print}' /etc/passwd                         //小于100跳过,否则显示 awk -F: 'BEGIN{i=1} {if(i<NF) print NR,NF,i++ }' /etc/passwd    awk -F: 'BEGIN{i=1} {if(i<NF) {print NR,NF} i++ }' /etc/passwd 另一种形式 awk -F: '{print ($3>100 ? "yes":"no")}'  /etc/passwd  awk -F: '{print ($3>100 ? $3":\tyes":$3":\tno")}'  /etc/passwd   while语句 awk -F: 'BEGIN{i=1} {while(i<NF) print NF,$i,i++}' /etc/passwd  7 root 1     数组 netstat -anp|awk 'NR!=1{a[$6]++} END{for (i in a) print i,"\t",a[i]}' netstat -anp|awk 'NR!=1{a[$6]++} END{for (i in a) printf "%-20s %-10s %-5s \n", i,"\t",a[i]}' 9523                               1        应用1 awk -F: '{print NF}' helloworld.sh                                                       //输出文件每行有多少字段 awk -F: '{print $1,$2,$3,$4,$5}' helloworld.sh                                 //输出前5个字段 awk -F: '{print $1,$2,$3,$4,$5}' OFS='\t' helloworld.sh                 //输出前5个字段并使用制表符分隔输出 awk -F: '{print NR,$1,$2,$3,$4,$5}' OFS='\t' helloworld.sh           //制表符分隔输出前5个字段,并打印行号   应用2 awk -F'[:#]' '{print NF}'  helloworld.sh                                                  //指定多个分隔符: #,输出每行多少字段 awk -F'[:#]' '{print $1,$2,$3,$4,$5,$6,$7}' OFS='\t' helloworld.sh   //制表符分隔输出多字段   应用3 awk -F'[:#/]' '{print NF}' helloworld.sh                                               //指定三个分隔符,并输出每行字段数 awk -F'[:#/]' '{print $1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12}' helloworld.sh     //制表符分隔输出多字段   应用4 计算/home目录下,普通文件的大小,使用KB作为单位 ls -l|awk 'BEGIN{sum=0} !/^d/{sum+=$5} END{print "total size is:",sum/1024,"KB"}' ls -l|awk 'BEGIN{sum=0} !/^d/{sum+=$5} END{print "total size is:",int(sum/1024),"KB"}'         //int是取整的意思   应用5 统计netstat -anp 状态为LISTEN和CONNECT的连接数量分别是多少 netstat -anp|awk '$6~/LISTEN|CONNECTED/{sum[$6]++} END{for (i in sum) printf "%-10s %-6s %-3s \n", i," ",sum[i]}'   应用6 统计/home目录下不同用户的普通文件的总数是多少? ls -l|awk 'NR!=1 && !/^d/{sum[$3]++} END{for (i in sum) printf "%-6s %-5s %-3s \n",i," ",sum[i]}'    mysql        199  root           374  统计/home目录下不同用户的普通文件的大小总size是多少? ls -l|awk 'NR!=1 && !/^d/{sum[$3]+=$5} END{for (i in sum) printf "%-6s %-5s %-3s %-2s \n",i," ",sum[i]/1024/1024,"MB"}'   应用7 输出成绩表 awk 'BEGIN{math=0;eng=0;com=0;printf "Lineno.   Name    No.    Math   English   Computer    Total\n";printf "------------------------------------------------------------\n"}{math+=$3; eng+=$4; com+=$5;printf "%-8s %-7s %-7s %-7s %-9s %-10s %-7s \n",NR,$1,$2,$3,$4,$5,$3+$4+$5} END{printf "------------------------------------------------------------\n";printf "%-24s %-7s %-9s %-20s \n","Total:",math,eng,com;printf "%-24s %-7s %-9s %-20s \n","Avg:",math/NR,eng/NR,com/NR}' test0
[root@localhost home]# cat test0  Marry   2143 78 84 77 Jack    2321 66 78 45 Tom     2122 48 77 71 Mike    2537 87 97 95 Bob     2415 40 57 62

 

awk 赋值运算符:a+5;等价于: a=a+5;其他同类

1 2 [root@Gin scripts]# awk 'BEGIN{a=5;a+=5;print a}' 10

awk逻辑运算符:

1 2 [root@Gin scripts]# awk 'BEGIN{a=1;b=2;print (a>2&&b>1,a=1||b>1)}' 0 1

判断表达式 a>2&&b>1为真还是为假,后面的表达式同理

awk正则运算符:

1 2 [root@Gin scripts]# awk 'BEGIN{a="100testaa";if(a~/100/) {print "ok"}}' ok
1 2 [root@Gin scripts]# echo|awk 'BEGIN{a="100testaaa"}a~/test/{print "ok"}' ok

关系运算符:

如: > < 可以作为字符串比较,也可以用作数值比较,关键看操作数如果是字符串就会转换为字符串比较。两个都为数字 才转为数值比较。字符串比较:按照ascii码顺序比较。

1 2 3 4 5 [root@Gin scripts]# awk 'BEGIN{a="11";if(a>=9){print "ok"}}' #无输出 [root@Gin scripts]# awk 'BEGIN{a=11;if(a>=9){print "ok"}}'  ok [root@Gin scripts]# awk 'BEGIN{a;if(a>=b){print "ok"}}' ok

awk 算术运算符:

说明,所有用作算术运算符进行操作,操作数自动转为数值,所有非数值都变为0。

1 2 3 4 [root@Gin scripts]# awk 'BEGIN{a="b";print a++,++a}' 0 2 [root@Gin scripts]# awk 'BEGIN{a="20b4";print a++,++a}' 20 22

这里的a++ , ++a与javascript语言一样:a++是先赋值加++;++a是先++再赋值

三目运算符 ?:

1 2 3 4 [root@Gin scripts]# awk 'BEGIN{a="b";print a=="b"?"ok":"err"}' ok [root@Gin scripts]# awk 'BEGIN{a="b";print a=="c"?"ok":"err"}' err

 常用 awk 内置变量 

 注:内置变量很多,参阅相关资料

字段分隔符 FS

FS="\t" 一个或多个 Tab 分隔

1 2 3 4 [root@Gin scripts]# cat tab.txt ww   CC        IDD [root@Gin scripts]# awk 'BEGIN{FS="\t+"}{print $1,$2,$3}' tab.txt ww   CC        IDD

FS="[[:space:]+]" 一个或多个空白空格,默认的 

1 2 3 4 5 6 [root@Gin scripts]# cat space.txt we are    studing awk now! [root@Gin scripts]# awk -F [[:space:]+] '{print $1,$2,$3,$4,$5}' space.txt we are   [root@Gin scripts]# awk -F [[:space:]+] '{print $1,$2}' space.txt we are

FS="[" ":]+" 以一个或多个空格或:分隔 

1 2 3 4 [root@Gin scripts]# cat hello.txt root:x:0:0:root:/root:/bin/bash [root@Gin scripts]# awk -F [" ":]+ '{print $1,$2,$3}' hello.txt root x 0

字段数量 NF 

1 2 3 4 5 [root@Gin scripts]# cat hello.txt root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin:888 [root@Gin scripts]# awk -F ":" 'NF==8{print $0}' hello.txt bin:x:1:1:bin:/bin:/sbin/nologin:888

记录数量 NR

1 2 [root@Gin scripts]# ifconfig eth0|awk -F [" ":]+ 'NR==2{print $4}'  ## NR==2也就是取第2行 192.168.17.129

RS 记录分隔符变量
将 FS 设置成"\n"告诉 awk 每个字段都占据一行。通过将 RS 设置成"",还会告诉 awk每个地址记录都由空白行分隔。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 [root@Gin scripts]# cat recode.txt Jimmy the Weasel 100 Pleasant Drive San Francisco,CA 123456   Big Tony 200 Incognito Ave. Suburbia,WA 64890 [root@Gin scripts]# cat awk.txt #!/bin/awk BEGIN {         FS="\n"         RS="" } {         print $1","$2","$3 } [root@Gin scripts]# awk -f awk.txt recode.txt Jimmy the Weasel,100 Pleasant Drive,San Francisco,CA 123456 Big Tony,200 Incognito Ave.,Suburbia,WA 64890

OFS 输出字段分隔符 

1 2 3 4 5 6 7 8 9 [root@Gin scripts]# cat hello.txt root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin:888 [root@Gin scripts]# awk 'BEGIN{FS=":"}{print $1","$2","$3}' hello.txt root,x,0 bin,x,1 [root@Gin scripts]# awk 'BEGIN{FS=":";OFS="#"}{print $1,$2,$3}' hello.txt root#x#0 bin#x#1

ORS 输出记录分隔符 

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 [root@Gin scripts]# cat recode.txt Jimmy the Weasel 100 Pleasant Drive San Francisco,CA 123456   Big Tony 200 Incognito Ave. Suburbia,WA 64890 [root@Gin scripts]# cat awk.txt #!/bin/awk BEGIN {         FS="\n"         RS=""         ORS="\n\n" } {         print $1","$2","$3 } [root@Gin scripts]# awk -f awk.txt recode.txt Jimmy the Weasel,100 Pleasant Drive,San Francisco,CA 123456   Big Tony,200 Incognito Ave.,Suburbia,WA 64890

 awk 正则 

 正则应用

规则表达式

awk '/REG/{action} ' file,/REG/为正则表达式,可以将$0 中,满足条件的记录送入到:action 进行处理

1 2 3 4 5 6 7 8 9 [root@Gin scripts]# awk '/root/{print $0}' passwd ##匹配所有包含root的行 root:x:0:0:root:/root:/bin/bash operator:x:11:0:operator:/root:/sbin/nologin   [root@Gin scripts]# awk -F: '$5~/root/{print $0}' passwd  ## 以分号作为分隔符,匹配第5个字段是root的行 root:x:0:0:root:/root:/bin/bash   [root@Gin scripts]# ifconfig eth0|awk 'BEGIN{FS="[[:space:]:]+"} NR==2{print $4}' 192.168.17.129

布尔表达式
awk '布尔表达式{action}' file 仅当对前面的布尔表达式求值为真时, awk 才执行代码块。

1 2 3 4 [root@Gin scripts]# awk -F: '$1=="root"{print $0}' passwd root:x:0:0:root:/root:/bin/bash [root@Gin scripts]# awk -F: '($1=="root")&&($5=="root") {print $0}' passwd root:x:0:0:root:/root:/bin/bash

 awk 的 if、循环和数组 

条件语句

awk 提供了非常好的类似于 C 语言的 if 语句。

1 2 3 4 5 6 7 8 9 10 11 12 13 {         if ($1=="foo"){                 if($2=="foo"){                         print "uno"                 }else{                         print "one"                 }         }elseif($1=="bar"){                 print "two"         }else{                 print "three"         } }

使用 if 语句还可以将代码: 

1 /matchme/ { print $1 $3 $4 }

转换成:

1 2 3 4 5 {   if ( $0 !~ /matchme/ ) {     print $1 $3 $4   } }

循环结构

我们已经看到了 awk 的 while 循环结构,它等同于相应的 C 语言 while 循环。 awk 还有"do...while"循环,它在代码块结尾处对条件求值,而不像标准 while 循环那样在开始处求值。

它类似于其它语言中的"repeat...until"循环。以下是一个示例:
do...while 示例

1 2 3 4 5 {     count=1do {         print "I get printed at least once no matter what"     while ( count !=1 ) }

与一般的 while 循环不同,由于在代码块之后对条件求值, "do...while"循环永远都至少执行一次。换句话说,当第一次遇到普通 while 循环时,如果条件为假,将永远不执行该循环。

for 循环

awk 允许创建 for 循环,它就象 while 循环,也等同于 C 语言的 for 循环:

1 2 3 for ( initial assignment; comparison; increment ) {     code block }

以下是一个简短示例: 

1 2 3 for ( x=1;x<=4;x++ ) {     print "iteration", x }

此段代码将打印: 

1 2 3 4 iteration1 iteration2 iteration3 iteration4

break 和 continue

此外,如同 C 语言一样, awk 提供了 break 和 continue 语句。使用这些语句可以更好地控制 awk 的循环结构。以下是迫切需要 break 语句的代码片断:

1 2 3 4 5 while 死循环 while (1) { print "forever and ever..." } while 死循环 1 永远代表是真,这个 while 循环将永远运行下去。

以下是一个只执行十次的循环: 

1 2 3 4 5 6 7 8 9 #break 语句示例 x=1 while(1) {   print "iteration", x   if ( x==10 ) {     break   }   x++ }

这里, break 语句用于“逃出”最深层的循环。 "break"使循环立即终止,并继续执行循环代码块后面的语句。
continue 语句补充了 break,其作用如下:

1 2 3 4 5 6 7 8 9 10 11 x=1while (1) {         if ( x==4 ) {         x++         continue     }     print "iteration", x     if ( x>20 ) {         break     }     x++ }

这段代码打印"iteration1"到"iteration21", "iteration4"除外。如果迭代等于 4,则增加 x并调用 continue 语句,该语句立即使 awk 开始执行下一个循环迭代,而不执行代码块的其余部分。如同 break 一样,

continue 语句适合各种 awk 迭代循环。在 for 循环主体中使用时, continue 将使循环控制变量自动增加。以下是一个等价循环:

1 2 3 4 5 6 for ( x=1;x<=21;x++ ) {     if ( x==4 ) {         continue     }     print "iteration", x }

在while 循环中时,在调用 continue 之前没有必要增加 x,因为 for 循环会自动增加 x。 

数组 

AWK 中的数组都是关联数组,数字索引也会转变为字符串索引 

1 2 3 4 5 6 7 8 9 10 11 {     cities[1]=”beijing”     cities[2]=”shanghai”     cities[“three”]=”guangzhou”     for( c in cities) {         print cities[c]     }     print cities[1]     print cities[“1”]     print cities[“three”] }

for…in 输出,因为数组是关联数组,默认是无序的。所以通过 for…in 得到是无序的数组。如果需要得到有序数组,需要通过下标获得。

数组的典型应用

用 awk 中查看服务器连接状态并汇总 

1 2 3 netstat -an|awk '/^tcp/{++s[$NF]}END{for(a in s)print a,s[a]}' ESTABLISHED 1 LISTEN 20

统计 web 日志访问流量,要求输出访问次数,请求页面或图片,每个请求的总大小,总访问流量的大小汇总

1 2 3 4 5 6 7 8 9 awk '{a[$7]+=$10;++b[$7];total+=$10}END{for(x in a)print b[x],x,a[x]|"sort -rn -k1";print "total size is :"total}' /app/log/access_log total size is :172230 21 /icons/poweredby.png 83076 14 / 70546 /icons/apache_pb.gif 18608 a[$7]+=$10 表示以第 7 列为下标的数组( $10 列为$7 列的大小),把他们大小累加得到 $7 每次访问的大小,后面的 for 循环有个取巧的地方, a 和 b 数组的下标相同,所以一 条 for 语句足矣

常用字符串函数

字符串函数的应用 

替换 

1 2 3 awk 'BEGIN{info="this is a test2010test!";gsub(/[0-9]+/,"!",info);print info}' this is a test!test! 在 info 中查找满足正则表达式, /[0-9]+/ 用”!”替换,并且替换后的值,赋值给 info 未 给 info 值,默认是$0

查找 

1 2 awk 'BEGIN{info="this is a test2010test!";print index(info,"test")?"ok":"no found";}' ok #未找到,返回 0

匹配查找 

1 2 awk 'BEGIN{info="this is a test2010test!";print match(info,/[0-9]+/)?"ok":"no found";}' ok #如果查找到数字则匹配成功返回 ok,否则失败,返回未找到

截取 

1 2 awk 'BEGIN{info="this is a test2010test!";print substr(info,4,10);}' s is a tes #从第 4 个 字符开始,截取 10 个长度字符串

分割 

1 2 3 4 awk 'BEGIN{info="this is a test";split(info,tA," ");print length(tA);for(k in tA){print k,tA[k];}}' 4 test 1 this 2 is 3 a #分割 info,动态创建数组 tA,awk for …in 循环,是一个无序的循环。 并不是从数组下标 1…n 开始

标签:%-,passwd,---,etc,awk,linux,print,root
From: https://www.cnblogs.com/kn-zheng/p/17447159.html

相关文章

  • Linux 初始化之 Systemd机制
    systemd是Linux下的一种init软件,由LennartPoettering带头开发,其开发目标是提供更优秀的框架以表示系统服务间的依赖关系,并依此实现系统初始化时服务的并行启动,同时达到降低Shell的系统开销的效果,最终代替现在常用的SystemV与BSD风格init程序。传统sysvinit使用inittab来决定运行......
  • 算法学习day36贪心part05-435、763、56
    packageLeetCode.greedypart05;importjava.util.Arrays;/***435.无重叠区间*给定一个区间的集合intervals,其中intervals[i]=[starti,endi]。返回需要移除区间的最小数量,使剩余区间互不重叠。*示例:*输入:intervals=[[1,2],[2,3],[3,4],[1,3]]*输出......
  • SQL优化-主键优化
        ......
  • 密码工程-大素数
    任务详情在openEuler(推荐)或Ubuntu或Windows(不推荐)中完成下面任务利大整数库(GMP或者OpenSSL),参考《密码工程》p113伪代码实现GenerateLargePrime函数(10‘)在测试代码中产生一个在范围l=2^255至u=2^256-1内的素数。(5‘)用OpenSSL验证你产生的素数是不是正确(5’)提交代......
  • OverTheWire攻关过程-Leviathan模块4
    我们打开lv3-lv4,查看信息依然信息很少我们登陆服务器查看信息带有sudo权限的文件应该是可执行文件执行,请输入密码错误退出机会只有一次调试过程要输入一个密码然后strcmp函数进行对比我们尝试输入这个"snlprintf\n"得到一个shell输入catcat/etc/leviathan_pass/leviathan4得到密码......
  • CMakeLists --- install和uninstall
    install假设生成了以下几个文件:静态库target1,动态库target2,可执行文件target3 1.安装文件至指定位置#只安装静态库install(TARGETStarget1LIBRARYDESTINATIONlib)#安装静态库,动态库,可执行文件install(TARGETStarget1target2target3LIBRARYDESTINATIONli......
  • linux 2种方式修改tmp目录的内存大小
    起因,tmp是临时目录,重启系统后目录的文件会清空,但是有时候你安装的软件依赖tmp进行临时存放文件,但tmp目录又太小。使用df-h查看/tmp目录的挂载点是tmpfs,这说明没有物理挂载设备。tmpfs有官方的介绍文章可以在评论区补充,谢谢。方法1:修改/etc/fstab文件的内容。vim/e......
  • HDU1524(博弈--有向无环图SG函数)
    题目:http://acm.hdu.edu.cn/showproblem.php?pid=1524题意:在一个有向无环图上有n个顶点,每一个顶点都只有一个棋子,有两个人,每次根据这个图只能将任意一颗棋子移动一步,如果到某一步玩家不能移动时,那么这个人就输.分析:本题是最典型的有向无环图的博弈,利用dfs把所有顶点的SG值......
  • 邮局--dp经典问题
    题目:http://poj.org/problem?id=1160题意: 一些村庄被建立在一条笔直的高速公路边上,我们用一条坐标轴来描述这条高速公路,每一个村庄的坐标都是整数,没有两个村庄坐标相同。两个村庄间的距离,定义为它们的坐标值差的绝对值。我们需要在一些村庄建立邮局——当然,并不是每一个村庄都......
  • 棋子--状态压缩dp
    题目描述:在一个N*N的棋盘上放棋子,每一个棋子的上下左右都没有棋子,也就是不相邻,一共有多少种放法?(N<=8)sample_input013sample_output1263分析:首先,我们可以逐行来摆放这些棋子,这样我们会发现,每一行的摆放状态只和上一行有关,这样我们可以采用递推的方式来解决。假设f[i......