Shell基础-awk脚本编程

一,awk简介

       awk是一种编程语言,用于在linux/unix下对文本和数据进行处理。数据可以来自标准输入、一个或多个文件,或其它命令的输出。
       awk的处理文本和数据的方式是这样的,它逐行扫描文件,从第一行到最后一行,寻找匹配的特定模式的行,并在这些行上进行你想要的操作。

二,awk的语法格式

        **awk [options] 'commands' filenames**
        awk中使用最多的选项-F的含义是定义输入字段分隔符,默认的分隔符是空格或制表符(tab)    
        awk中commands部分可以分为三段,分别为**行处理前、行处理、行处理后**。下面的例子:
              awk  'BEGIN{print 1/2} {print "ok"} END{print"........"}'  /etc/hosts,如果hosts文件中有3行,那么执行这条命令的输出是:     

              0.5
              ok
              ok
              ok
              .........
         ## awk的命令格式
         awk ‘pattern’ filename    示例:awk -F: ‘/root/’ /etc/passwd
         awk '{action}' filename    示例: awk -F: '{print $1}'  /etc/passwd
         awk 'pattern {action}' filename 示例: awk 'BEGIN{FS=":"} /root/{print $1, $3}' /etc/passwd
         注意上面命令中-F: 等价于FS=":"

三、awk工作原理

       awk -F: '{print $1, $3}' /etc/passwd      
       第一步:awk使用一行作为输入,并将这一行赋给内部变量$0,每一行也可称为一个记录,以换行符结束
       第二步:行被:(默认为空格或制表符)分解为字段(或域),每个字段存储在已编号的变量中,从$1开始。awk如何知道用空格来分隔字段的?因为有一个内部变量FS来确定字段分隔符。初始时,FS赋为空格。
       第三步:awk打印字段时,将以设置的方法使用print函数打印,awk在打印的字段间加上空格,因为$1,$3之间有一个逗号。逗号比较特殊,它映射为另一个内部变量,称为输出字段分隔符OFS,OFS默认为空格。
       第四步:awk输出之后,将从文件中获取另一行,并将其存储在$0,覆盖原来的内容,然后将新的字符串分隔成字段进行处理。该过程将持续到所有行处理完毕。

四、awk内部变量

      $0:     awk变量$0保存当前记录的内容   #awk -F: '{print $0}' /etc/passwd
      NR:    总记录的编号
      FNR:  当前输入文件的记录编号
      NF:    当前记录的字段数目
      FS:    输入字段分隔符,默认情况下是空格或制表符
      OFS:  输出字段分隔符
      RS:    输入记录分隔符,默认为换行符
      ORS:  输出记录分隔符
               awk -F: 'BEGIN{ORS=" "} {print $0}' passwd  > passwd1 将文件passwd中的每一行输出到passwd1中,并且每行之间都有一个空格,因为修改了ORS的默认值。

五、awk格式化输出

      ## printf函数
           awk  -F: ‘{printf "%-15s %-10s %-15s\n", $1,$2,$3}’ /etc/passwd
           注意%s是字符类型,%d是数值类型,%f是浮点类型。15指的是占15字符。-表示左对齐,默认是右对齐。需要注意的是printf默认不会在行尾自动换行,加上\n后就可以进行换行了。
      ## awk的模式和动作
            任何awk语句都由**模式**和**动作**组成。模式部分决定动作语句何时触发及触发事件。处理即对数据进行的操作。如果省略模式部分,动作将时刻保持执行状态。模式可以是任何条件语句或复合语句或正则表达式。模式包括两个特殊字段BEGIN和END。使用BEGIN语句设置计数和打印头。BEGIN语句使用在任何文本浏览器动作之前,之后文本浏览动作依据输入文本开始执行。END语句用来在awk完成文本浏览动作后打印输出文本总数和结尾状态。
      **匹配记录(整行):**
      awk '$0 ~ /^alice/'  /etc/passwd      输出匹配行
      awk '$0 !~ /^alice/'  /ect/passwd     输出不匹配行
      **匹配字段:匹配操作符(~ !~)**
      awk -F: '$1 ~ /^alice/' /etc/passwd  输出第一个字段是alice的行
      awk -F: '$NF !~ /bash$/' /etc/passwd   输出最后一个字段不是bash的行
      **需要注意的是,模式中是可以使用关系运算符的,比如<、<=、==、!=等,条件表达式也是可以的**
      awk -F: 'if(条件) {动作} else{动作}' /etc/passwd
      **模式中也是可以有算术运算和逻辑操作符(&&,||,!)和符合模式**

六、awk脚本编程

        ## if格式
              {if(表达式) {语句;语句;....}else{语句}}
        ## while循环
              awk -F: '{i=1; while(i<=NF){print $i; i++}}' /etc/passwd
              上面命令的含义是打印passwd文件中每一行的每一列。
              awk -F: '/^root/{i=1; while(i<=NF){print $i; i++}}' /etc/passwd
              上面命令的含义是打印passwd文件中以root开头行的每一列。
        ## for循环
               awk 'BEGIN{for(i=1; i<=5; i++){print i}}'  C风格的
        ## 数组
               awk中的数组默认支持关联数组。
               数组遍历的时候我们使用索引遍历。
               awk -F: '{username[x++]=$1 END{for(i in username) {print i,username[i]} }' /etc/passwd
               注意:变量i是索引。

七、awk使用外部变量的方法

第一种情况,在双引号的情况下使用外部变量

第一种情况
第二种情况,使用awk的参数-v(建议使用)
使用-v参数的方法使用外部变量

猜你喜欢

转载自blog.csdn.net/xiaoan08133192/article/details/112941372