gawk

简介

    AWK是一种优良的文本处理工具。它不仅是 Linux 中也是任何环境中现有的功能最强大的数据处理引擎之一。AWK 提供了极其强大的功能:可以进行样式装入、流控制、数学运算符、进程控制语句甚至于内置的变量和函数。它具备了一个完整的语言所应具有的几乎所有精美特性。实际上 AWK 的确拥有自己的语言:AWK 程序设计语言, 三位创建者已将它正式定义为“样式扫描和处理语言”。它允许您创建简短的程序,这些程序读取输入文件、为数据排序、处理数据、对输入执行计算以及生成报表,还有无数其他的功能。最简单地说, AWK 是一种用于处理文本的编程语言工具。

awk经过改进生成的新的版本nawk,gawk,现在默认linux系统下日常使用的是gawk,用命令可以查看正在应用的awk的来源(ls -l /bin/awk )

awk

    gawk – pattern scanning and processing language

基本用法

    awk [options]  'program' file1,file2,…..

      options常用选项:

           -F[]:指定分隔符,使用[]可以指定多个分隔符

           -v var=varl:自定义变量

      program组成:

          PATTERN {ACTION STATEMENT},由语句组成,语句分隔符是";"

          ACTION:print,printf

    1 print 常用输出命令

        用法:print item1, item2, …

        要点:

            (1) 逗号分隔符;

            (2) 输出的各item可以字符串,也可以是数值;当前记录的字段、变量或awk的表达式;

            (3) 如省略item,相当于print $0; 

    

     注意:

        BEGIN

        有时候可能在处理数据前运行脚本,比如为报告创建开头部分,BEGIN关键字就是用来做这个的,它会强制gawk在读取数据前执行BEGIN关键字后制指定的程序脚本.

        END

        跟BEGIN关键字类似,END关键字允许你指定一个程序脚本,gawk会在读完数据后执行它的.

    示例1:awk程序读取文本文件并显示第1数据字段值

    awk '{print $1}' test5.txt 

    blob.png

    示例2:显示出/etc/fstab 文件里面的第2段和第4段数据,开头加个hello

    tail -5 /etc/fstab | awk '{print "hello",$2,$4}'

    blob.png

    

    2.变量

        2.1 内建变量

        2.2 自定义变量

             (1) -v var=value

                 变量名区分字符大小写;

             (2) 在program中直接定义

    示例3:给test4这个文件用awk 处理之前设置一个开头部分,处理完成后设置一个结尾部分.

    awk 'BEGIN{print "This is the beginning";print "userid  shell";print "——  ——";FS=":"}''{print $1,$7}'END'{print "Here is the end"}' test4.txt 

    blob.png

    示例4 以冒号为字段分隔符显示/etc/passwd文件里面的第1字段

     awk -v FS=":" '{print $1}' /etc/passwd

    blob.png

    示例5:处理后显示出test6.txt的第1,2,3数据字段值

    awk 'BEGIN{FS="."}{print $1,$2,$3}' test6.txt

    blob.png

    示例6: 通过设置OFS变量,你可以在输出中使用任意字符来分割字段

    awk 'BEGIN{FS=".";OFS="-"}{print $1,$2,$3}' test6.txt 

    awk -v FS="." -v OFS="-" '{print $1,$2,$3}' test6.txt 这种写法也可以

    blob.png

    示例7: 显示出/etc/passwd 第1段,第3段和第7段,并且以冒号字段分隔符显示出来

    awk -v FS=":" -v OFS=":" '{print $1,$3,$7}'

    blob.png

    示例8:以空白为换行符, 以#号为数据行为分隔符显示出/etc/passwd

    awk -v RS=' ' -v ORS='#' '{print}' /etc/passwd

    blob.png

    示例9:显示/etc/fstab 每一行多少字段

    awk '{print NF}' /etc/fstab

    blob.png

    示例10:显示/etc/fstab 最后一个字段

     awk '{print $NF}' /etc/fstab

   blob.png     

   示例11:统计/etc/fstab行数对行直接编号

    awk '{print NR}' /etc/fstab 

    blob.png

    示例12:对/etc/fstab /etc/issue 各文件分别计数,行数

    awk '{print FNR}' /etc/fstab /etc/issue

    blob.png

    示例13:显示命令行参数的个数

    awk 'BEGIN{print ARGC}' /etc/fstab /etc/issue

    blob.png

    示例14:显示命令行参数数组的第3个参数

    awk 'BEGIN{print ARGV[2]}' /etc/fstab /etc/issue

    blob.png

    3 printf命令

        格式化输出:printf FORMAT, item1, item2, … 

     

         (1) FORMAT必须给出; 

         (2) 不会自动换行,需要显式给出换行控制符,\n

         (3) FORMAT中需要分别为后面的每个item指定一个格式化符号;

        

         格式符:

         修饰符:

         #[.#]:第一个数字控制显示的宽度;第二个#表示小数点后的精度;

         %3.1f

         -: 左对齐

         +:显示数值的符号

    示例15:显示/etc/passwd 文件中的第一字段,格式化输出。

    awk -F: '{printf "%s\n",$1}' /etc/passwd

    blob.png

    示例16:显示/etc/passwd 文件中的第1和第3个字段,第1段格式化字符串,第三段格式化十进制整数并且第3段前面要显示UID:

    awk -F: '{printf "%s, UID:%d\n",$1,$3}' /etc/passwd

    blob.png

    示例17:显示/etc/passwd 文件中的第1和第三个字段,第1段格式化字符串并且左对齐,第三段格式化十进制整数并且第3段前面要显示UID:

    awk -F: '{printf "%-15s UID:%d\n",$1,$3}' /etc/passwd

    blob.png

    4.操作符

     示例18:以冒号为字段分隔符,判断/etc/passwd 文件中的第三个字段,大于500的为显示为普通用户,否则其他的显示为管理员或者是系统用户。

    awk -F: '{$3>=500?usertype="Common User":usertype="Sysadmin or SysUser";printf "%15s:%-s\n",$1,usertype}' /etc/passwd

    blob.png

    示例19:以冒号为字段分隔符,找出/etc/passwd 文件中第1个字段为root显示出来

    awk -F":" '$1=="root"{print $1}' /etc/passwd

    blob.png

    5 PATTERN

         (1) empty:空模式,匹配每一行;

         (2) /regular expression/:仅处理能够被此处的模式匹配到的行;

         (3) relational expression: 关系表达式;结果有“真”有“假”;结果为“真”才会被处理;

         真:结果为非0值,非空字符串;

         (4) line ranges:行范围,

         startline,endline:/pat1/,/pat2/

         注意: 不支持直接给出数字的格式

         (5) BEGIN/END模式

         BEGIN{}: 仅在开始处理文件中的文本之前执行一次;

         END{}:仅在文本处理完成之后执行一次;

    示例20:匹配/etc/passw文件中结尾是bash的,显示出第1段和最后一段

        awk -F":" '$NF~/bash$/{print $1,$NF}' /etc/passwd

        blob.png

    示例21:显示出test8.txt文件中root开头一直到myuser10结尾的行

    awk -F":" '/^root/,/^myuser10/{print $1}' test8.txt 

    blob.png

    示例22:匹配/etc/passwd文件中行号大于等于2和小于等于10,显示出第1个字段

    awk -F":" '(NR>=2&&NR<=10){print $1}' /etc/passwd

    blob.png

    6.控制语句

        6.1 if-else

            语法:if(condition) statement [else statement]  

    示例23:判断如果ID号大于等于500 显示出来是普通用户 否则就是管理员或者系统用户 

     awk -F: '{if($3>=500) {printf "Common user: %s\n",$1} else {printf "root or Sysuser: %s\n",$1}}' /etc/passwd

     blob.png            

    示例24:磁盘使用比率大于%10就显示出来

    df -h | awk -F[%] '/^\/dev/{print $1}' | awk '{if($NF>=10) print $1}'

    blob.png

        6.2 while循环

            语法:while(condition) statement

                条件“真”,进入循环;条件“假”,退出循环;

    示例25:显示boot/grub/grub.conf 文件中以空格开头kernel哪一行字段内容和字符的个数

    awk '/^[[:space:]]*kernel/{i=1;while(i<=NF) {print $i,length($i); i++}}' /boot/grub/grub.conf 

    blob.png

    示例26:显示boot/grub/grub.conf 文件中以空格开头kernel哪一行字段内容和字符的个数,字符数大于8的才显示

    awk '/^[[:space:]]*kernel/{i=1;while(i<=NF) {if(length($i)>=7) {print $i,length($i)}; i++}}' /boot/grub/grub.conf 

    blob.png

     

        6.3 for循环

            语法:for(expr1;expr2;expr3) statement

                for(variable assignment;condition;iteration process) {for-body}

    示例27:显示boot/grub/grub.conf 文件中以空格开头kernel哪一行字段内容和字符的个数(用for循环)

    awk '/^[[:space:]]*kernel/{for(i=1;i<=NF;i++) {print $i,length($i)}}' /boot/grub/grub.conf 

     blob.png 

    6.4 next

        提前结束对本行的处理而直接进入下一行;

    示例28:显示用户id 号为偶数的用户

    awk -F: '{if($3%2!=0) next; print $1,$3}' /etc/passwd

    blob.png

    7.array

        关联数组:array[index-expression]

            index-expression:

             (1) 可使用任意字符串;字符串要使用双引号;

             (2) 如果某数组元素事先不存在,在引用时,awk会自动创建此元素,并将其值初始化为“空串”;

            

             若要判断数组中是否存在某元素,要使用"index in array"格式进行;

        示例29:weekdays赋值第一个元素Monday,第二个元素Tuesday,并打印出第一个元素

        awk 'BEGIN{weekdays["mon"]="Monday";weekdays["tue"]="Tuesday";print weekdays["tue"]}'

   blob.png

 

        若要遍历数组中的每个元素,要使用for循环

    示例30:weekdays赋值第一个元素Monday,第二个元素Tuesday,并且都打印出来

        awk 'BEGIN{weekdays["mon"]="Monday";weekdays["tue"]="Tuesday";for(i in weekdays) {print weekdays[i]}}'

    blob.png

    示例31:netstat -tan 统计tcp状态出现了多少次

    netstat -tan | awk '/^tcp\>/{state[$NF]++}END{for(i in state) { print i,state[i]}}'

    blob.png

    示例32:统计/var/log/httpd/access_log 文件中每个IP访问多少次

    awk '{ip[$1]++}END{for(i in ip) {print i,ip[i]}}' /var/log/httpd/access_log

    8.函数

        

        8.1 内置函数

         数值处理:

         rand():返回0和1之间一个随机数;

         字符串处理:

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

         sub(r,s,[t]):以r表示的模式来查找t所表示的字符中的匹配的内容,并将其第一次出现替换为s所表示的内容;

         gsub(r,s,[t]):以r表示的模式来查找t所表示的字符中的匹配的内容,并将其所有出现均替换为s所表示的内容;

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

    

    

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

联系我们

400-080-6560

在线咨询

工作时间:周一至周五,9:30-18:30,节假日同时也值班

QR code