重庆网站建设公司重庆言西早工作室欢迎您!
当前位置
言西早网站建设 > 新闻中心 > 公司新闻 > awk数组的用法讲解

awk数组的用法讲解

发布时间:2020-01-09 17:35:44 作者:重庆言西早工作室 阅读:
  在其他的编程语言中,数组的下标都是从0开始的,也就是说,如果想反向引用数组中的第一个元素,则需要引用对应的下标[0],在awk中数组也是通过引用下标的方法,但是在awk中数组的下标是从1开始的,在其他语言中,你可能会习惯于先“声明”一个数组,在awk中,则不用这样,直接为数组的元素赋值即可(其实如果自己给数组赋值,下标从1或者从0开始那就无所谓了!)
 
  在声明数组时,可能值很多,命令太长,降低命令可读性,所以使用反斜杠“\”,来进行换行,效果是完全一样的,代码如下所示:
 
  [zkpk@masteras]$awk'BEGIN{arr[1]="one";arr[2]="two";arr[3]="three"\
 
  ;arr[4]="four";printarr[3]}'
 
  three
 
  [zkpk@masteras]$awk'BEGIN{arr[1]="one";arr[2]="two";arr[3]="three";arr[4]="four";printarr[3]}'
 
  three
 
  数组的元素设置为空,是允许的,当数组中没有某个元素而直接引用它的时候,它默认被赋值为空,所以判断某个元素是否存在,不能采用数组元素值为空的方法,而应该采用下面的方法:
 
  [zkpk@masteras]$awk'BEGIN{arr[1]="one";arr[2]="two";arr[3]="three";if(4inarr){print"fourinthisarr"}}'
 
  [zkpk@masteras]$awk'BEGIN{arr[1]="one";arr[2]="two";arr[3]="three";if(3inarr){print"threeinthisarr"}}'
 
  threeinthisarr
 
  也可以采用取反的方式(使用运算符!)
 
  [zkpk@masteras]$awk'BEGIN{arr[1]="one";arr[2]="two";arr[3]="three";if(!(4inarr)){print"fournotinthisarr"}}'
 
  fournotinthisarr
 
  awk数组下标
 
  在awk中数组的下标不仅可以是“数字”,还可以是“任意字符串”,其实,awk中的数组本来就是“关联数组”,之所以先用数字作为下标举例子是为了方便之前的习惯,能够有个好的过渡,不过,以数字作为数组的下标在某些场景有一定的优势,但是本质上也是“关联数组”,awk默认会把“数字”下标转换成“字符串”,所以它本质上还是一个使用字符串作为下标的“关联数组”
 
  删除数组元素
 
  使用delete可以删除数组中的元素,也可以使用delete删除整个数组
 
  [zkpk@masteras]$awk'BEGIN{arr[1]="one";arr[2]="two";arr[3]="three";\
 
  >deletearr[1];printarr[1]}'
 
  ____(空)
 
  [zkpk@masteras]$awk'BEGIN{arr[1]="one";arr[2]="two";arr[3]="three";\
 
  printarr[1];printarr[3];deletearr;printarr[1]}'
 
  one
 
  three
 
  ____(空)
 
  使用for循环遍历数组
 
  语法:for(变量in数组名){代码语句}
 
  注:其中变量循环的是数组的下标
 
  [zkpk@masteras]$awk'BEGIN{arr[1]="one";arr[2]="two";arr[3]="three";arr[4]="four";\
 
  >for(iinarr){printarr[i]}}'
 
  four
 
  one
 
  two
 
  three
 
  #无序的打印数组元素,进一步证明其是“关联数组”
 
  #有序的打印数组元素
 
  [zkpk@masteras]$awk'BEGIN{arr[1]="one";arr[2]="two";arr[3]="three";arr[4]="four";\
 
  for(i=1;i<=4;i++){printarr[i]}}'
 
  one
 
  two
 
  three
 
  four
 
  awk数组使用实例
 
  [zkpk@masteras]$awk'BEGIN{a=1;printa;a=a+1;printa}'
 
  1
 
  2
 
  [zkpk@masteras]$awk'BEGIN{a=1;printa;a++;printa}'
 
  1
 
  2
 
  将变量a设置为1,对其进行自加运算,则其数值会增加1,这不难理解,那么如果变量a是一个字符串哪?
 
  [zkpk@masteras]$awk'BEGIN{a="test";printa;a++;printa}'
 
  test
 
  当a的值为字符串时,竟然也可以参与运算,而且可以看出,字符串被当成数字0参与运算,那么空字符串参与运算时也会被当成0运算吗?
 
  [zkpk@masteras]$awk'BEGIN{a="";printa;a++;printa}'
 
  ____(空)
 
  结果显示,空字符串在参与运算时也会被当做数字0,之前我们说过,当我们引用数组中一个不存在的元素,元素被赋值成空字符串,当对这个元素进行自加运算时,元素的值就变成了1,因此当我们对一个不存在的元素进行自加运算后,这个元素的值就变成了自加的次数,自加x次,元素的值就被赋值为x,自加y次元素的值就被赋值为y,所以我们可以通过awk数组的这个特性来统计文本中某字符串出现的次数,代码如下所示
 
  [zkpk@masteras]$cattext
 
  Alice
 
  Bob
 
  Tom
 
  Peter
 
  Alice
 
  Alice
 
  Tom
 
  Bob
 
  Peter
 
  Bob
 
  [zkpk@masteras]$awk'{count[$1]++};END{for(iincount){printi,count[i]}}'text
 
  Bob3
 
  Tom2
 
  Alice3
 
  Peter2
 
  这回你该发现awk数组这个特性的强大所在了吧,好,也许你会说我不用awk照样可以统计啊,代码如下所示:
 
  [zkpk@masteras]$cattext|sort|uniq-c
 
  3Alice
 
  3Bob
 
  2Peter
 
  2Tom
 
  好吧,我承认你这个思路很棒,但是你看看下面例子哪?统计文本中人名出现的次数
 
  [zkpk@masteras]$cat-tEtext
 
  Alice^IBob$
 
  Bob^IAliceAlicePeter$
 
  TomBob$
 
  PeterAlice$
 
  AliceTom$
 
  Alice^I^ITom$
 
  TomPeter$
 
  BobBob$
 
  PeterAlice$
 
  BobAliceAliceTom$
 
  #我们可以看出上面的文本中人名之间的分隔符有制表符,也有空格,来吧,统计人名出现的次数吧,
 
  #我使用awk数组的方式可以这样统计
 
  [zkpk@masteras]$awk'{for(i=1;i<=NF;i++){count[$i]++}}END{for(jincount)\
 
  {printj,count[j]}}'text
 
  Bob6
 
  Tom5
 
  Alice9
 
  Peter4
 
  但若你不用awk,非得用其他命令实现可以参考如下代码(^_^)
 
  [zkpk@masteras]$cattext|tr-s"\t"""|tr-s"""\n"|sort|uniq-c
 
  9Alice
 
  6Bob
 
  4Peter
 
  5Tom
 
  本文介绍了awk数组的基本使用方法,但是要学会灵活的运用,我在上面的示例中也写出了一些可以在某种程度上替换awk数组的方式,所以本文不单单是介绍awk数组该如何使用,而是如何在合适的场景,选择出最优的解决方案,快速高效的解决问题。
 
awk数组的用法讲解
 
  如何在awk中初始化数组
 
  awk的数组其实很好理解。一般编程语言的数组,其下标只能是数字,比如a[3],表示数组a的第四个元素。
 
  但是awk的不同,其下标可以是任意字符或者字符串。比如a[bob],表示数组a的一个元素,它的下标是"bob"。
 
  比如有个文本文件alex.txt:
 
  a1
 
  b2
 
  c3
 
  a4
 
  b5
 
  a6
 
  如果我们想统计以a开头的行后面的数字之和,就是“1+4+6”,我们用awk怎么做呢:
 
  catalex.txt|awk‘{if(!array[$1]){array[$1]=$2;}
 
  elae{arrary[$1]=array[$1]+$2;}}END{printarray[a];}’
 
  命令中有个数组array,当读取alex.txt第一行时,$1是“a”,array[a]刚开始是“”(空字符串),所以!array[a]就为真,那么array[a]=1,数组array就有了第一个元素array[a].
 
  同理,读取第二行之后结果array[a]=1,array[b]=2,数组array就有了2个元素。
 
  第三行之后结果是array[a]=1,array[b]=2,array[c]=3,数组array就有了3个元素。
 
  第四行之后结果是array[a]=5(1+4,4为第四行的$2),array[b]=2,array[c]=3
 
  第五行之后结果是array[a]=5,array[b]=7,array[c]=3
 
  第六行之后结果是array[a]=11,array[b]=7,array[c]=3
 
  END的意思是读取完文件所有行后执行的语句,打印出数组第一个元素array[a].
 
  awk中如何获取数组元素个数
 
  使用awk的内置函数split,将第三个字段根据分隔符“-”分割并存入数组,最后跟随$1和$2逐个打印。
 
  $echo"aaa31-2-3-4-5"|awk'{n=split($3,a,"-");for(i=1;i<=n;i++)print$1,$2,a[i]}'aaa31aaa32aaa33aaa34aaa35