awk初步学习(不断总结)

1.输入文件中间多了换行符处理

这里写图片描述
  本来的文件是每行4个字段,但是有的行中间多了换行符,导致读出来的文件变成了这样。使用awk进行处理。

cat 222.txt|awk  'BEGIN{a=0}{   
    if((a+NF)<4){
        printf $0;a=a+NF
    }
    else{
        printf $0"\n";a=0
    }
}'

// cat 222.txt|awk  'BEGIN{a=0}{ 指令1 } 
    读取文件内容通过管道传递到后面使用awk进行处理
    BEGIN{a=0} 命令在初始化阶段就执行,所以a在最开始为0
    { 指令1 }  是awk在每行读取时需要执行的命令(awk是行读取并处理,防止内存爆炸)
NF表示的是读进来的行有多少列,如果小于指定的列数,打印,但是不换行,因为还有字段在下一行,并且a=现有列数。
继续读取下一行,和上一行不完整的列拼接起来,即执行的else。然后换行,并另a0.
当来一行是正常的行,直接打印。

  但是,如果是自己构造的数据,打印会出错,如下面的图:
这里写图片描述
  这是因为我们在构造数据的时候直接换行(如7之后的8,没有加上本应该有间隔符),而实际的业务表格是有这个间隔符的,且间隔符之后多了一个换行符导致形成多行,所以上诉代码在实际业务执行就不会两个数贴在一起。
  自己构造数据的时候可以在7之后加上对应的间隔符,或者代码改成如下形式:

自己构造的时候少了本应该的间隔符,所以打印的时候加上
cat 222.txt|awk  'BEGIN{a=0}{   
    if((a+NF)<4){
        printf $0" ";a=a+NF    //在$0后加了空格
    }
    else{
        printf $0"\n";a=0
    }
}'

这里写图片描述
  这样就正常了。

2.awk常见命令:

这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述

3.例题

1.该例题转载自:http://blog.chinaunix.net/uid-10540984-id-1185098.html
3 5 6 7
2 3 1 0
4 5 6 9
2 3 4 4
2 2 1 0
4 5 0 9
假如把2列和3列的值作为新的第5列,第5列的平均值为avg5,求第5列中大于avg5的行数。

1:
awk '{x+=$2+$3;a[NR]=$2+$3}END{y=x/NR;for(i in a){if(y<a[i])z++}print z}' file

[解析]
   这个题初看,觉得简单,仔细看又觉得有难度,否则腾讯这些大企业也不会出这么简单的题了,呵呵。首先来分析,第5列的值很好办 2 + 3,但是求平均值比较麻烦,麻烦的原因是只有最后END才可以通过累加的x的值来除以行数然后得出平均值,又有个一个新的问题,这时候已经END了,求出了平均值但是无法再从新历遍全文去比较每行的 2 + 3 是否大于该平均值,怎么着?总得有个东西来装 2 + 3 的结果吧,目的是将 2 + 3的结果放入一个容器,在END求出平均值后再拿出来判断比较,惯例请出我们的老朋友数组。最后的大家都能看懂了吧。
  

2:
awk 'BEGIN{while(getline<"file"){x+=$2+$3;i++};y=x/i}{if($2+$3>y)z++}END{print z}' file

[解析]

   这是7月22日更新的新命令,我新学会的一种处理手段,在BEGIN模块中利用 while(getline<”file”) 来提前历遍全文,在BEGIN中我们可以看到,我已经把 2 + 3的和累加给了x变量,但是求平均值必须要知道行数,怎么办呢?这时候在BEGIN中NR还是0,当然可以搞定了,我们这时候就不用NR自己建个变量来保存行数就好了嘛,这样我们可以顺利的在BEGIN模块中就已经求出了平均数了。然后按照正常的执行流程再逐行判断第2列和第3列的和是否大于这个平均数,最后打印统计结果。
2.转载至 https://blog.csdn.net/wangbran/article/details/81033371
有个一个文件 file,内容如下

1.1.1.1 st_000012 ajgoahgoahgoahgghg
2.2.2.2 st_000014 ajgoaoghaughughgu
3.3.3.3 st_000015 alfjoigrhuogrub
4.4.4.4 st_000016 ajgoaghkaahgoahgghg
1.1.1.1 st_000019 ajgoalllllghughgu
5.5.5.5 st_000015 alfjoigrhuogrub

找到第一列中出现最多的ip,第二列中出现最多的用户名,必须要用awk

awk ‘BEGIN{max_h=0;max_i=0}{ip[$1]++;host[$2]++};END{for(i in ip){if(ip[i]>max_i){max_i=ip[i];ip_m=i}}print max_i,ip_m;for(j in host){if(host[j]>max_h){max_h=host[j];host_m=j}}print max_h,host_m}’ file

结果
2 1.1.1.1
2 st_000015

猜你喜欢

转载自blog.csdn.net/qq_15220357/article/details/81708272
今日推荐