简述awk命令及用法

栏目: 服务器 · 发布时间: 6年前

内容简介:AWK是一种处理文本文件的语言,是一个强大的文本分析工具。

简述awk命令及用法

AWK是一种处理文本文件的语言,是一个强大的文本分析工具。

语法

awk [options]'program' {filenames}

参数

-F:指明输入时用到的字段分隔符,默认是空格符
-v var=value: 自定义变量

program

program: PATTERN{ACTION STATEMENTS}
         语句之间用分号分隔
  • print
    • 格式 :print item1,item2,….
      $0:表示整个当前行
      $1:每行第一个字段
      NR:number of record, 总行数;
      NF:number of field,字段数量
          {print NF}:打印每行的字段
          {print $NF}:打印第NF个字段值(最后一个字段的值)
      FNR:单个数据文件处理的行数
      \t:制表符
      \n:换行符

      简述awk命令及用法

    • 实例
      • F & $0
        #输出整行,awk {print} /etc/passwd = awk '{print $0}' /etc/passwd
        ~]# awk {print} /etc/passwd
        ~]# awk '{print $0}' /etc/passwd
        root:x:0:0:root:/root:/bin/bash
        bin:x:1:1:bin:/bin:/sbin/nologin
        daemon:x:2:2:daemon:/sbin:/sbin/nologin
        
        #":"为分格符输出第一个字符
        ~]# awk -F":" '{print $1}'  /etc/passwd
        root
        bin
        daemon
        
        #$1与$3相连输出,不分隔
        ~]# awk -F":" '{print $1 $3}'  /etc/passwd 
        root0
        bin1
        daemon2
        
        #多了一个逗号,$1与$3使用空白分格分隔
        ~]# awk -F":" '{print $1,$3}'  /etc/passwd
        root 0
        bin 1
        daemon 2
        
        #$1与$3使用分格符分隔,自定义分隔符
        ~]# awk -F":" '{print $1 "," $3}'  /etc/passwd
        root,0
        bin,1
        daemon,2        
        ~]# awk -F":" '{print $1 "-" $3}'  /etc/passwd
        root-0
        bin-1
        daemon-2    
        
        #自定义输出内容
        ~]# awk -F":" '{print "Username:" $1" \t Uid:" $3 }' /etc/passwd
        Username:root    Uid:0
        Username:bin     Uid:1
      • NF
        #显示每行有多少字段
        ~]# awk -F: '{print NF}' /etc/passwd  
        7
        7
        7
        
        #将每行第NF个字段的值打印出来
         ~]# awk -F: '{print $NF}' /etc/passwd
        /bin/bash
        /sbin/nologin
        /sbin/nologin
        
        #只输出字段数=7的行
        ~]# awk -F":" 'NF==7 {print }' /etc/passwd
        root:x:0:0:root:/root:/bin/bash
        bin:x:1:1:bin:/bin:/sbin/nologin
        daemon:x:2:2:daemon:/sbin:/sbin/nologin
        
        #输出字段数>2的行
        ~]# awk -F":" 'NF>2{print $0}' /etc/passwd
        root:x:0:0:root:/root:/bin/bash
        bin:x:1:1:bin:/bin:/sbin/nologin
        daemon:x:2:2:daemon:/sbin:/sbin/nologin
      • NR
        #输出每行的行号
        localhost ~]# awk '{print NR,$0}' /etc/passwd 
        1 root:x:0:0:root:/root:/bin/bash
        2 bin:x:1:1:bin:/bin:/sbin/nologin
        3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
        
        #显示第5行
        localhost ~]# awk -F: 'NR==5{print}'  /etc/passwd 
        lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
        
        #显示5行以后的数据,并在前面显示行号
        localhost ~]# awk -F: 'NR>5{print NR ,$0}'  /etc/passwd 
        6 sync:x:5:0:sync:/sbin:/bin/sync
        7 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
        8 halt:x:7:0:halt:/sbin:/sbin/halt
        .....
        
        #显示5行和第8行,并在前面显示行号
        localhost ~]#awk -F: 'NR==5 || NR == 8 {print NR ,$0}'  /etc/passwd 
        5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
        8 halt:x:7:0:halt:/sbin:/sbin/halt
      • FNR&NR
        localhost tmp]# cat data3
        hello
        hello
        hello
        localhost tmp]#  awk '{print $0 ,"\t""FNR="FNR,"NR="NR}' data3 data3
        hello   FNR=1 NR=1
        hello   FNR=2 NR=2
        hello   FNR=3 NR=3
        hello   FNR=1 NR=4
        hello   FNR=2 NR=5
        hello   FNR=3 NR=6
  • 格式化打印printf
    printf FORMAT, item1, item2, ...
        (1) FORMAT必须给出; 
        (2) 不会自动换行,需要显式给出换行控制符,\n
        (3) FORMAT中需要分别为后面的每个item指定一个格式化符号;
    • 格式符:
      %c: 显示字符的ASCII码;
      %d, %i: 显示十进制整数;
      %e, %E: 科学计数法数值显示;
      %f:显示为浮点数;
      %g, %G:以科学计数法或浮点形式显示数值;
      %s:显示字符串;
      %u:无符号整数;
      %%: 显示%自身;
    • 修饰符
      #[.#]:第一个数字控制显示的宽度;第二个#表示小数点后的精度;
      -: 左对齐
      +:显示数值的符号
    • 说明
      (1). 可以在"%"和字母之间插进数字表示最大场宽。 
              例如:%3d 表示输出3位整型数, 不够3位右对齐。 
              %9.2f 表示输出场宽为9的浮点数, 其中小数位为2, 整数位为6,小数点占一位, 不够9位右对齐。 
              %8s 表示输出8个字符的字符串, 不够8个字符右对齐。 
      如果字符串的长度、或整型数位数超过说明的场宽, 将按其实际长度输出.但对浮点数, 若整数部分位数超过了说明的整数位宽度, 将按实际整数位输出;若小数部分位数超过了说明的小数位宽度, 则按说明的宽度以四舍五入输出.
      另外, 若想在输出值前加一些0, 就应在场宽项前加个0。 
              例如: %04d 表示在输出一个小于4位的数值时, 将在前面补0使其总宽度为4位。 
      如果用浮点数表示字符或整型量的输出格式, 小数点后的数字代表最大宽度,小数点前的数字代表最小宽度。 
              例如: %6.9s 表示显示一个长度不小于6且不大于9的字符串。若大于9, 则第9个字符以后的内容将被删除。
      
      (2). 可以在"%"和字母之间加小写字母l, 表示输出的是长型数。 
              例如: %ld 表示输出long整数 
                  %lf 表示输出double浮点数 
      
      (3). 可以控制输出左对齐或右对齐, 即在"%"和字母之间加入一个"-" 号可说明输出为左对齐, 否则为右对齐。 
              例如: %-7d 表示输出7位整数左对齐 
              %-10s 表示输出10个字符左对齐
    • 实例
      #%d 显示十进制整数
      ~]#  echo "1.7 2.52" | awk '{printf ("%d\n",$2)}'
      2
      
      #%f 显示浮点数       
      ~]# echo "1.7 2.52" | awk '{printf ("%f\n",$1)}'
      1.700000
      
      #四舍五入输入整数
      ~]# echo "1.5" | awk '{printf ("%.f\n",$1)}'    
      2
      echo "1.4" | awk '{printf ("%.f\n",$1)}'    
      1
      
      #以3位长度、1位小数,"."占一位,浮点换行输出第2个域(四舍五入)
      ~]# echo "1.7 2.52" | awk '{printf ("%3.1f\n",$2)}'
      2.5
      
      #以6位长度,其中整数占2位,不足2位空格补足,“.”占一位,小数占3位,不足3位用0补足
      ~]# echo "1.7 2.52" | awk '{printf ("%6.3f\n",$2)}'
      2.520
      
      #指数形式的浮点数输出
      ~]# echo "1.7 2.52" | awk '{printf ("%e\n",$1)}'
      1.700000e+00
      
      #用0补充格式
      ~]# echo "123 1" | awk '{printf("%d\t%03d\n",$1,$2)}'
      123     001
  • BEGIN/END模式
    BEGIN{}: 仅在开始处理文件中的文本之前执行一次;
    END{}:仅在文本处理完成之后执行一次;
    • 实例
      #开头显示“The data of passwd”
      localhost ~]# awk 'BEGIN{print "The data of passwd"} {print}' /etc/passwd
      The data of passwd
      root:x:0:0:root:/root:/bin/bash
      bin:x:1:1:bin:/bin:/sbin/nologin
      daemon:x:2:2:daemon:/sbin:/sbin/nologin
      
      #显示第一行,并在开头和末尾显示“The data of passwd”
      localhost ~]# awk 'BEGIN{print "print /etc/passwd"} NR==1{print} END{print "print /etc/passwd"}' /etc/passwd
      print /etc/passwd
      root:x:0:0:root:/root:/bin/bash
      print /etc/passwd
  • 使用变量
    • 内建变量:字段和记录分隔符变量
      FS:input field seperator,输入字段分隔符,默认为空白字符
      OFS:output field seperator,输出字段分隔符, 默认空白字符;
      RS:input record seperator,输入时的换行符;
      ORS:output record seperator,输出时的换行符;
      FIELDWIDTHS:指定列
      • 实例
      • FS&OFS
        #自定义分输入隔符为“:”
        localhost ~]#awk 'BEGIN{FS=":"} NR<4{print $1,$2,$3}' /etc/passwd
        root x 0
        bin x 1
        daemon x 2
        
        #自定义分输入隔符为“:”,输出分隔符为“-”
        localhost ~]# awk 'BEGIN{FS=":" ;OFS="-"} NR<4{print $1,$2,$3}' /etc/passwd
        root-x-0
        bin-x-1
        daemon-x-2
      • RS&ORS
        #输入时以回车符为分隔符,空白行为换行符,
        localhost tmp]# cat data2
        Riley Mullen
        123 Main Street
        Chicago, IL 60601
        (312)555-1234
        
        Frank Williams
        456 Oak Street
        Indianapolis, IN 46201
        (317)555-9876
        
        Haley Snell
        4231 Elm Street
        Detroit, MI
        (313)555-4938
        localhost tmp]# awk 'BEGIN{FS="\n"; RS=""}{print $1 ,$4}' data2
        Riley Mullen (312)555-1234
        Frank Williams (317)555-9876
        Haley Snell (313)555-4938
      • FIELDWIDTHS
        #以特定列为分隔
        localhost tmp]# cat data1
        1005.3247596.37
        115-2.349194.00
        05810.1298100.1
        localhost tmp]# awk 'BEGIN{FIELDWIDTHS="3 5 2 5"} {print $1,$2,$3,$4}' data1
        100 5.324 75 96.37
        115 -2.34 91 94.00
        058 10.12 98 100.1
    • 自定义变量
      • 在脚本中给变量复制
        变量名可以是任意数目的字母、数字和下划线,但不能以数字开头
        • 实例
          localhost ~]#awk 'BEGIN{test="hello everyone";print test}'
          hello everyone
          
          localhost ~]# awk 'BEGIN{x=4;x=x*2+3;print x}'
          11
      • 在命令行上给变量复制
        localhost tmp]# cat data4
        data11 data12 data13
        data21 data22 data23
        data31 data32 data33
        
        localhost tmp]# cat script1
        BEGIN{print "The starting value is",n}{print $n}
        
        localhost tmp]# awk -v n=3 -f script1 data4
        The starting value is 3
        data13
        data23
        data33
  • 数组变量
    var[index] = element
    var:变量名
    index:索引值
    element:数据元素值
    • 遍历数组变量

      for (var in array)
      {
          statements
      }

      for语句在每次循环时将关联数组array下一个索引值赋给变量var,然后执行一遍statements

      • 实例
        localhost ~]# awk 'BEGIN{var["a"] =1;var["b"]=2;var["c"]=3;var["d"]=4;for (i in var) {print var[i]}}'
        1
        2
        3
        4
        
        #统计IP链接数
        localhost ~]# awk '{ip[$1]++}END{for(i in ip) {print i,ip[i]}}' /var/log/httpd/access_log
        192.168.1.48 10
        
        #统计tcp链接状态和数量,IPV4
        localhost ~]# netstat -tan | awk '/^tcp\>/{state[$NF]++}END{for(i in state) { print i,state[i]}}'
        LISTEN 2
        ESTABLISHED 3
        
        #统计/etc/fstab文件中每个文件系统类型出现的次数
        localhost ~]# awk '/^UUID/{fs[$3]++}END{for(i in fs) {print i,fs[i]}}' /etc/fstab
        xfs 1
        
        #统计指定文件中每个单词出现的次数;
        localhost ~]# awk '{for(i=1;i<=NF;i++){count[$i]++}}END{for(i in count) {print i,count[i]}}' /etc/fstab
  • 字符串匹配
    //          纯字符匹配   
    !//         纯字符不匹配  
     ~//        字段值匹配    
    !~//        字段值不匹配   
    ~/a1|a2/    字段值匹配a1或a2
    • 实例
      #显示 mysql 相关信息
      localhost ~]# awk '/mysql/{print $0}' /etc/passwd 
      mysql:x:27:27:MariaDB Server:/var/lib/mysql:/sbin/nologin
      
      #显示非mysql
      localhost ~]# awk '!/mysql/{print $0}' /etc/passwd 
      
      #显示mail和mysql
      localhost ~]# awk '/mail|mysql/{print $0}' /etc/passwd 
      mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
      mysql:x:27:27:MariaDB Server:/var/lib/mysql:/sbin/nologin
      
      #显示$1匹配mail 
      localhost ~]# awk -F: '$1~/mail/{print $1}' /etc/passwd 
      mail
  • 操作符
    • 算数操作符
      x+y: 加
      x-y:减
      x*y:乘
      x/y:除
      x^y:次方
      x%y:余数
    • 赋值操作符
      = : x=y
      +=: x+=5    (x=x+5)
      -=: x-=5    (x=x-5)
      /=: x/=5    (x=x/5)
      %=: x%=5    (x=x%5)
      ^=: x^=5    (x=x^5)
      ++: x++     (x=x+1)
      --: x--     (x=x-1)
    • 比较操作符
      >
      >=
      <
      <=
      !=
      ==
    • 模式匹配符
      ~:是否匹配
      !~:是否不匹配
    • 逻辑操作符:
      &&
      ||
      !
    • 条件表达式
      selector?if-true-expression:if-false-expression
      
      实例:
       ~]# awk -F: '{$3>=1000?usertype="Common User":usertype="Sysadmin or SysUser";printf "%15s:%-s\n",$1,usertype}' /etc/passwd
                 root:Sysadmin or SysUser
                  bin:Sysadmin or SysUser
               daemon:Sysadmin or SysUser
                  adm:Sysadmin or SysUser
                   lp:Sysadmin or SysUser
                 sync:Sysadmin or SysUser
  • 控制语句
    • if语句

      if(condition) {statments} 
      if(condition) {statments} else {statements}

      实例:

      #简单的if语句
      ~]# awk -F: '{if($NF=="/bin/bash") print $1}' /etc/passwd
      root
      centos
      test
      linux
      testuser
      
      #if-else语句
      ~]# awk -F: '{if($3>=1000) {printf "Common user: %s\n",$1} else {printf "root or Sysuser: %s\n",$1}}' /etc/passwd
      ~]#awk -F: '{if($3>=1000) printf "Common user: %s\n",$1; else printf "root or Sysuser: %s\n",$1}' /etc/passwd
      root or Sysuser: root
      root or Sysuser: bin
      root or Sysuser: daemon
      root or Sysuser: adm
      root or Sysuser: lp
      
      #在if中执行多条语句和if-else语句
      [root@localhost tmp]# cat data1
      10
      5
      13
      50
      34
      [root@localhost tmp]# awk '{if ($1>20) {x= $1*2; print $1,x}}' data1
      50 100
      34 68
      ~]# awk '{if($1>20) print $1*2;else print $1/2}' data1
      5
      2.5
      6.5
      100
      68
      
      #打印磁盘使用率超过10%的
       ~]#  df -h | awk -F[%] '/^\/dev/{print $1}' | awk '{if($NF>=10) print $1}'
      /dev/mapper/cl-root
      /dev/sda1
    • while循环

      while(conditon) {statments}
      条件“真”,进入循环;条件“假”,退出循环

      实例:对一行内的多个字段逐一类似处理时使用;对数组中的各元素逐一处理时使用

      ~]# awk '/^[[:space:]]*linux16/{i=1;while(i<=NF) {print $i,length($i); i++}}' /etc/grub2.cfg
      linux16 7
      /vmlinuz-3.10.0-514.el7.x86_64 30
      root=/dev/mapper/cl-root 24
      ro 2
      crashkernel=auto 16
      rd.lvm.lv=cl/root 17
      rd.lvm.lv=cl/swap 17
      rhgb 4
      quiet 5
      LANG=en_US.UTF-8 16
      linux16 7
      /vmlinuz-0-rescue-071d709683fd4359a4845645d1906b29 50
      root=/dev/mapper/cl-root 24
      ro 2
      crashkernel=auto 16
      rd.lvm.lv=cl/root 17
      rd.lvm.lv=cl/swap 17
      rhgb 4
      quiet 5
      
      ~]# awk '/^[[:space:]]*linux16/{i=1;while(i<=NF) {if(length($i)>=7) {print $i,length($i)}; i++}}' /etc/grub2.cfg
      linux16 7
      /vmlinuz-3.10.0-514.el7.x86_64 30
      root=/dev/mapper/cl-root 24
      crashkernel=auto 16
      rd.lvm.lv=cl/root 17
      rd.lvm.lv=cl/swap 17
      LANG=en_US.UTF-8 16
      linux16 7
      /vmlinuz-0-rescue-071d709683fd4359a4845645d1906b29 50
      root=/dev/mapper/cl-root 24
      crashkernel=auto 16
      rd.lvm.lv=cl/root 17
      rd.lvm.lv=cl/swap 17
    • do-while循环
      至少执行一次循环体
    • for循环

      for(expr1;expr2;expr3) {statements}

      实例

      ~]# awk '/^[[:space:]]*linux16/{for(i=1;i<=NF;i++) {print $i,length($i)}}' /etc/grub2.cfg
      linux16 7
      /vmlinuz-3.10.0-514.el7.x86_64 30
      root=/dev/mapper/cl-root 24
      ro 2
      crashkernel=auto 16
      rd.lvm.lv=cl/root 17
      rd.lvm.lv=cl/swap 17
      rhgb 4
      quiet 5
      LANG=en_US.UTF-8 16
      linux16 7
      /vmlinuz-0-rescue-071d709683fd4359a4845645d1906b29 50
      root=/dev/mapper/cl-root 24
      ro 2
      crashkernel=auto 16
      rd.lvm.lv=cl/root 17
      rd.lvm.lv=cl/swap 17
      rhgb 4
      quiet 5
  • 内建函数
    • 数学函数
      atan2(x, y)     x/y的反正切,x和y以弧度为单位
      cos(x)          x的余弦,x以弧度为单位
      exp(x)          x的指数函数
      int(x)          x的整数部分,取靠近零一侧的值
      log(x)          x的自然对数
      rand( )         比0大比1小的随机浮点值
      sin(x)          x的正弦,x以弧度为单位
      sqrt(x)         x的平方根
      srand(x)        为计算随机数指定一个种子值
    • 字符串函数
      asort(s [,d])               将数组s按数据元素值排序。索引值会被替换成表示新的 排序 顺序的连续数字。另外,如果指定了d,则排序后的数组会存储在数组d中
      asorti(s [,d])              将数组s按索引值排序。生成的数组会将索引值作为数据元素值,用连续数字索引来表明排序顺序。另外如果指定了d,排序后的数组会存储在数组d中
      gensub(r, s, h [, t])       查找变量$0或目标字符串t(如果提供了的话)来匹配正则表达式r。如果h是一个以g或G开头的字符串,就用s替换掉匹配的文本。如果h是一个数字,它表示要替换掉第h处r匹配的地方
      gsub(r, s [,t])             查找变量$0或目标字符串t(如果提供了的话)来匹配正则表达式r。如果找到了,就全部替换成字符串s
      index(s, t)                 返回字符串t在字符串s中的索引值,如果没找到的话返回0
      length([s])                 返回字符串s的长度;如果没有指定的话,返回$0的长度
      match(s, r [,a])            返回字符串s中正则表达式r出现位置的索引。如果指定了数组a,它会存储s中匹配正则表达式的那部分
      split(s, a [,r])            将s用FS字符或正则表达式r(如果指定了的话)分开放到数组a中。返回字段的总数
      sprintf(format,variables)   用提供的format和variables返回一个类似于printf输出的字符串
      sub(r, s [,t])              在变量$0或目标字符串t中查找正则表达式r的匹配。如果找到了,就用字符串s替换掉第一处匹配
      substr(s, i [,n])           返回s中从索引值i开始的n个字符组成的子字符串。如果未提供n,则返回s剩下的部分
      tolower(s)                  将s中的所有字符转换成小写
      toupper(s)                  将s中的所有字符转换成大写
    • 时间函数
      mktime(datespec)            将一个按YYYY MM DD HH MM SS [DST]格式指定的日期转换成时间戳值①
      strftime(format[,timestamp])将当前时间的时间戳或timestamp(如果提供了的话)转化格式化日期(采用 shell 函数date()的格式)
      systime( )                  返回当前时间的时间戳

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Understanding Computation

Understanding Computation

Tom Stuart / O'Reilly Media / 2013-6-3 / USD 39.99

Finally, you can learn computation theory and programming language design in an engaging, practical way. Understanding Computation explains theoretical computer science in a context you'll recognize, ......一起来看看 《Understanding Computation》 这本书的介绍吧!

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具