linux三剑客之awk

awk

   
   
    简介:是一个优良的文本处理工具,Linux及Unix环境中现有的功能最强大的数据处理引擎之一。这种编程及数据操作语言的最大功能
          取决于一个人所拥有的知识。awk经过改进生成的新的版本nawk,gawk,现在默认linux系统下日常使用的是gawk,用命令可以查
          看正在应用的awk的来源(ls -l /bin/awk )
    名称由来:三位作者名字的首字母,Aho, Weinberger, Kernighan
    格式:
        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语句块
         program通常是被单引号或双引号中
    常用选项
        -F:指定分割符,默认为空白分隔符
        -v:定义变量,每个变量前添加-v
      
    基本格式:awk [options] 'program' file…
      
       program组成:patter{action}两个部分组成
           patter:决定动作的何时触发和触发事件
           (BEGIN,END)
          action对数据进行处理,放在{}内指明
          ( print, printf)
          
    分割符、域和记录
    • awk执行时, 由分隔符分隔的字段(域)标记$1,$2..$n称为域标识。 $0为所有域,注意:和shell中变量$符含义不同
    • 文件的每一行称为记录
    • 省略action,则默认执行 print $0 的操作。
    
    工作原理
        第一步:执行BEGIN{action;… }语句块中的语句
        第二步:从文件或标准输入(stdin)读取一行,然后执行pattern{action;… }语句块,它逐行扫描文件,从第一行到最后一行重
        复这个过程,直到文件全部被读取完毕。
        第三步:当读至输入流末尾时,执行END{action;…}语句块
        BEGIN:语句块在awk开始从输入流中读取行之前被执行,这是一个可选的语句块,比如变量初始化、打印输出表格的表头等语句通常
            可以写在BEGIN语句块中
        END:语句块在awk从输入流中读取完所有的行之后即被执行,比如打印所有行的分析结果这类信息汇总都是在END语句块中完成,它
            也是一个可选语句块
      pattern:语句块中的通用命令是最重要的部分,也是可选的。如果没有提供pattern语句块,则默认执行{ print },即打印每一个读取
              到的行, awk读取的每一行都会执行该语句块
     
       action动作
           print格式:print item1,item2
           (1)用逗号隔开,输入结果以空格分割
          (2)item的值可以是字符串(用双引号引起来)、变量、当前记录(行)的字段、数值、awk表达式
          (3)如果不写item默认打印$0
          
       awk 变量
           内置变量:
           FS:指定字段的分隔符,默认为空格
               awk -v FS=":" '{print $1}' file
               awk  -F  ":"  '{print $1}' file
           OFS:输出字段的分隔符,默认的为空白
               awk - v FS=‘:’ - v OFS=‘:’ '{print $1,$3,$7}’ /etc/passwd
           RS:输入记录分隔符, 指定输入时的换行符,原换行符仍有效
            awk -v RS=' ' ‘{print }’ /etc/passwd
           NF:字段数量
               awk  -F: '{print NF}' /etc/passwd
             NR:行号(多个文件时,将不单独统计每个文件的行号)
               awk  '{print NR,$0}' /etc/passwd
           FNR:分别显示每个文件的行号
               awk    '{print FNR,$0}' /etc/passwd /etc/fstab
            
           FILENAME:当前文件名
               awk '{print FILENAME}’ /etc/fstab 
                       
            ARGV:数组,保存的是命令行所给定的各参数
                awk ‘BEGIN {print ARGV[0]}’ /etc/fstab
        自动变量:
            (1) - v var=value
              变量名区分字符大小写             
            (2) 在program中直接定义
             awk - v test='hello gawk' '{print test}' /etc/fstab  :/etc/fstab有几行将会打印出几行‘hellow gawk’
                         awk - v test='hello gawk' 'BEGIN{print test}'
                         awk 'BEGIN{test="hello,gawk";print test}'  
                                    
        printf
          格式:printf "格式",item1,item2.....
                       (1) 必须指定FORMAT
                       (2) 不会自动换行,需要显式给出换行控制符, \n
                       (3) FORMAT中需要分别为后面每个item指定格式符                             
                          
          格式符:与item一一对应
              %c:显示字符的ASCII码
              %s:字符
              %d %i:数字十进制格式
              %f:浮点型
              %e %E:科学计数法表示
              %u:显示无符号整数
              %g %G:科学计数法表示或者浮点型表示
              %%:显示%本身
              
          修饰符:
             #[.#]:第一个数字控制显示的宽度;第二个#表示小数点后精度, %3.1f
             - : 左对齐(默认右对齐) %-15s
             +:显示数值的正负符号 %+d
             
          awk实例:
              awk -F: '{printf "username:%-15s \t  UID:%+4d\n",$1,$3}' /etc/passwd   
              
        awk操作符
        
            算术操作符:
             x+y, x- y, x*y, x/y, x^y, x%y
                    - x: 转换为负数
                    +x: 转换为数值 
                    [root@mycentos6 ~]# awk -v a=10 -v b=10  'BEGIN{print a + b}'
                    20
                    [root@mycentos6 ~]# 
                      
                    字符串操作符:没有符号的操作符,字符串连接  
                    [root@mycentos6 ~]# awk -v a=10 -v b=10  'BEGIN{print a  b}'
                    1010
                    [root@mycentos6 ~]#       
                  
       赋值操作符:
                    =, +=, - =, *=, /=, %=, ^=
                    ++, --  
                 比较操作符:
                    >, >=, <, <=, !=, ==
                 模式匹配符:
                    ~:左边是否和右边匹配包含
                    !~:是否不匹配
                 [root@mycentos6 ~]# cat /etc/passwd |awk '$0 !~ /root/' |wc -l
                    35
                [root@mycentos6 ~]# cat /etc/passwd |awk '$0 !~ /^root/' |wc -l
                    36
                [root@mycentos6 ~]#
                
                 逻辑操作符: &&, ||, !   
                     示例:注意{}位置
                    • 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/passwd
                条件表达示    
                    selector?if- true- expression:if- false- expression
                    selector:为条件,如果为真执行?后面的语句,如果为假则执行:后面的语句
                    示例:
                    [root@mycentos6 ~]# awk -F: '{$3>=500?type="commonuser":type="systemuser"; \ :分行显示,可以直接写一行
                    > printf "%-10s \t %s\n ",$1,type}' /etc/passwd    
                              
    PATTERN
           
              作用:根据pattern条件,过滤匹配的行,再做处理    
               (1)如果未指定: 空模式,匹配每一行         
               (2) /regular expression/:仅处理能够模式匹配到的行,需要用 / /括起来
                    awk '/^UUID/{print $1}' /etc/fstab
                    awk '!/^UUID/{print $1}' /etc/fstab    
              (3) relational expression: 关系表达式;结果有“真”有“假”;结果为“
                    真”才会被处理;
                   真:结果为非0值,非空字符串 ‘0,1’:结果为真
                   假:结果为空字符串  
              示例:
                   [root@mycentos6 ~]# awk -F: '$NF=="/bin/bash"{print $1 ,$3}' /etc/passwd
                    root 0
                    mysql 27
                    user1 500
                    user2 501
                    user3 502
                   [root@mycentos6 ~]# 
                   
                   [root@mycentos6 ~]# seq 10 |awk 'i=!i'
                    1
                    3
                    5
                    7
                    9
                    [root@mycentos6 ~]# 
             (4) line ranges: 行范围
                startline,endline: /pat1/,/pat2/ 不支持直接给出数字格式
                awk - F: '/^root/,/^nobody/{print $1}' /etc/passwd
                awk - F: '(NR>=2&&NR<=10){print $1}' /etc/passwd      
                    
              [root@mycentos6 ~]# awk -F: '/^root/,/^user2/{print $1}' /etc/passwd       
              
              5) BEGIN/END模式
                BEGIN{}: 仅在开始处理文件中的文本之前执行一次 使用于打印标题等
                END{}:仅在文本处理完成之后执行一次

    

    示例:
        1、awk - F : 'BEGIN {print "USER USERID"} {print$1":"$3} END{print "end file"}' /etc/passwd
        2、awk - F: 'BEGIN{print " USER UID \n ---------------- "}{print $1,$3}'END{print "=============="}
            /etc/passwd
   
   
    awk  action分类
        (1) Expressions:算术,比较表达式等
        (2) Control statements: if, while等
        (3) Compound statements:组合语句
        (4) input statements
        (5) output statements: print等

    awk 控制语句:if else

   

      
     
    '{ if(condition) statement [else statement]}'
    '{if(condition1){statement1}else if(condition2){statement 2}else{statement3}}'
     
    示例:
         1、判断磁盘使用率,如果大于70,打印磁盘名
         2、判断成绩

      1、

        9.png

      2、

        10.png

         11.png

    while 语句: 

     while循环:语法 while(condition) statement
      使用场景:对一行内的多个字段逐一类似处理时使用
           对数组中的各元素逐一处理时使用 
           
     示例:

    12.png 

  13.png

    awk中do …while语句

        语法: do statement while(condition)    
      意义:无论真假,至少执行一次循环体
         示例:
         awk 'BEGIN{ total=0;i=0;do{total+=i;i++;}while(i<=100);print total}'

    14.png   

    

    for 语句:

       
        语法: for(expr1;expr2;expr3) statement
            for(variable assignment;condition;iteration process) {forbody}
        特殊用法:能够遍历数组中的元素;
            语法: for(var in array) {for- body}
            
        示例: awk '/^[[:space:]]*linux16/{for(i=1;i<=NF;i++) {print$i,length($i)}}' /etc/grub2.cfg

    

    性能比较:

        

       

               #time (awk 'BEGIN{total=0;for(i=0;i<=10000;i++){total+=i;};print total;}')
        #time(total=0;for i in $(seq 10000);dototal=$(($total+i));done;echo $total)

        blob.png

       关键字:time

        blob.png     

    awk控制语句

        
        switch语句
        语法: switch(expression) {case VALUE1 or /REGEXP/:statement; case VALUE2 or /REGEXP2/: statement;...; default: statement}
        
        break和continue    
        next:提前结束对本行处理而直接进入下一行处理( awk自身循环)

    blob.png

    blob.png

    blob.png

    awk数组:

        关联数组: array[index- expression]
            index- expression:
            (1) 可使用任意字符串;字符串要使用双引号括起来
            (2)如果某数组元素事先不存在,在引用时, awk会自动创建此元素,并将其值初始化为“空串”
            (3)若要判断数组中是否存在某元素,要使用“index in array”格式进行遍历
            
            awk '!a[$0]++' dupfile:过滤掉重复行 ,我用以下方法写也许更容易理解

        blob.png

       blob.png

     1、要理解:awk '!a[$0]++'先看下面程序,数组在默认不给值时,当对空值数组进行++操作,数组的值会自动+1

        blob.png 

    2、详细说明!a[$0]++的值 当awk读取f1时, a[111]值为空——>!a[111]值为1 ,因此打印$0;a[111]++;a[111]值为2;当再遇见a[111],也就是相同的两行

      a[111]=2;!a[111]=0 ;一次不在打印111这一行,a[111]++ ;a[111]=3     

    

    awk数组 :

     
      若要遍历数组中的每个元素,要使用for循环
      格式:for(var in array) {for- body}
      注意: var会遍历array的每个索引,所以var的值也就是索引的值

      实例1、
      blob.png

     实例2、查看每个tcp状态的连接数

       blob.png  

     实例3、查看每个ip地址访问http链接数

        blob.png

        blob.png

    awk函数:        

        数值处理:
        rand():返回0和1之间一个随机数 ,必须加srand()结合使用

        awk 'BEGIN{srand(); for (i=1;i<=10;i++)print int(rand()*100) }'

        blob.png

        

        字符串处理:

        • length([s]):返回指定字符串的长度

        blob.png

        

       sub(r,s,[t]):对t字符串进行搜索r表示的模式匹配的内容,并将第一个匹配的内容替换为s

        blob.png   

      gsub(r,s,[t]):对t字符串进行搜索r表示的模式匹配的内容,并全部替换为s所表示的内容

        blob.png     

      split(s,array,[r]):以r为分隔符切割字符s,并将切割后的结果保存至array所表示的数组中

    blob.png

        

      自定义函数格式:

        格式:
        function name ( parameter, parameter, … ) {
        statements
        return expression

        }
     blob.png

    awk中调用shell命令      

        system命令
        空格是awk中的字符串连接符,如果system中需要使用 awk中的变量可以使用空格分隔,或者说除了 awk的变量外其他一律
        用 ""引用起来。
        awk BEGIN'{system("hostname") }'

        awk 'BEGIN{score=100; system("echo your score is " score) }'

    blob.png

    
    将awk程序写成脚本,直接调用或执行

       

        #cat f1.awk
        if($3>=1000)print $1,$3}

        #awk – F: – f f1.awk /etc/passwd

        

        #cat f2.awk
        #!/bin/awk –f
        #this is a awk script
        {if($3>=1000)print $1,$3}
        #chmod +x f2.awk

        #f2.awk –F: /etc/passwd

    

    向awk脚本传递参数      

        格式:awkfile var=value var2=value2… Inputfile        

        示例:
        #cat test.awk
        #!/bin/awk –f
        {if($3 >=min && $3<=max)print $1,$3}
        #chmod +x test.awk

        #test.awk – F: min=100 max=200 /etc/passwd

        blob.png

    练习题:

        1、 统计/etc/fstab文件中每个文件系统类型出现的次数

        blob.png

        2、 统计/etc/fstab文件中每个单词出现的次数;
        blob.png

        

原创文章,作者:wangnannan,如若转载,请注明出处:http://www.178linux.com/47860

(0)
wangnannanwangnannan
上一篇 2016-12-05
下一篇 2016-12-05

相关推荐

  • 第一周作业

    一:计算机的组成和功能 主要分为五个部分:控制器、运算器、存储器、输入、输出 CPU :包含控制器和运算器、寄存器、缓存 存储器:内存,RAM(Random Access Memory) 输入:下指令,提供数据等 输出:输出数据加工的结果     微型计算机系统组成:      …

    Linux干货 2016-12-06
  • 简述开源协议

    简述开源协议 现在一说到智能手机,相信很容易就会想到苹果和安卓。安卓搭载的Android是一种基于Linux的自由及开源的操作系统,苹果手机搭载OS X是苹果公司为Mac系列产品开发的专属操作系统。    安卓手机凭借其开源的特性达到与苹果系统分庭伉礼的地位,又凭借其开源的价格优势,牢牢把控手机设备的中低端市场,其市场占有率远远…

    Linux干货 2017-03-26
  • MAN 手册各章节功能及快捷键键位介绍

      man命令在linux下属于一种帮助命令,man手册提供了比较齐全的帮助格式,它大致分为8个章节 一.各个章节如下 1 – commands 1-普通的命令 (用户命令,  可由任何人启动的) 2 – system calls 2-系统调用,如open,write之类的(通过这个,至少可以很方便的查到调用这个函…

    Linux干货 2016-10-17
  • 8.网络基础知识

    1、请描述网桥、集线器、二层交换机、三层交换机、路由器的功能、使用场景与区别。 网桥:网桥就是把2个不同的网段桥接起来;可隔离冲突域。 集线器:集线器就是把多根以太网线或光纤集合连接在同一段物理介质下的装置;工作在物理层;不能隔离冲突域。 二层交换机:工作于OSI模型的第2层(数据链路层),故而称为二层交换机。二层交换技术的发展已经比较成熟,二层交换机属数据…

    Linux干货 2017-08-21
  • 复习-RAID原理详解

    一、RAID RAID:冗余磁盘阵列,将多个磁盘不同的方式组成阵列,作为单一磁盘使用;通过RAID,大幅提高了I/O能力、容错性。 二、RAID级别 不同的磁盘阵列组成模式,称为磁盘级别,不同的RAID级别可提供不同的I/O能力提升、磁盘可用率和容错性 1、RAID 0 条带卷 strip  用两块和两块以上磁盘组成,RAID控制器将数据平均切割成…

    Linux干货 2016-07-04
  • Linux命令中特殊符号的用法

    Linux命令中特殊符号的用法 在马哥教育学习了将近一周的Linux运维,由最初对Linux系统的一无所知,到了解了Linux的发展历程,学习了一些基本命令,惊叹于Linux的强大功能。下面根据我学到的,介绍一下关于Linux命令中特殊符号的用法。 $的用法 1.$()或’’引用命令执行的结果 例如:如果我们想要创建一个以当前日期命名的目录,可以执行 #mk…

    2017-07-15