AWK简单入门

AWK简单入门

简介

awk是一种编程语言,其名称得自于它的创始人 Alfred Aho 、Peter Weinberger 和 Brian Kernighan 姓氏的首个字母 ,用于在linux/unix下对文本和数据进行处理。grep,sed,awk被称为linux中的‘‘三剑客’

​ grep 更适合单纯的查找或匹配文本

​ sed 更适合编辑匹配到的文本

​ awk 更适合格式化文本,对文本进行较复杂格式处理

简单使用

  1. 首先通过nestat命令列出开放的端口,并写入到文件

    netstat -tunlp > netstat.txt
    
    //文件内容如下
    Proto Recv-Q Send-Q Local Address     Foreign Address   State     PID/Program name   
    tcp        0      0 0.0.0.0:3306      0.0.0.0:*         LISTEN    -                   
    tcp        0      0 0.0.0.0:21        0.0.0.0:*         LISTEN    -                   
    tcp        0      0 0.0.0.0:22        0.0.0.0:*         LISTEN    -                   
    tcp        0      0 127.0.0.1:631     0.0.0.0:*         LISTEN    -                   
    tcp        0      0 127.0.0.1:6011    0.0.0.0:*         LISTEN    -                   
    tcp        0      0 :::22             :::*              LISTEN    -                   
    tcp        0      0 ::1:631           :::*              LISTEN    -                   
    tcp        0      0 ::1:6011          :::*              LISTEN    -                   
    udp        0      0 0.0.0.0:631       0.0.0.0:*                   -
    
  2. 可以看到文件结构是10行7列,通过awk我们可以很方便的把第一列和第四列打印出来

    awk '{print $1,$4}' netstat.txt
    
    //执行命令结果
    Proto Local
    tcp 0.0.0.0:3306
    tcp 0.0.0.0:21
    tcp 0.0.0.0:22
    tcp 127.0.0.1:631
    tcp 127.0.0.1:6011
    tcp :::22
    tcp ::1:631
    tcp ::1:6011
    udp 0.0.0.0:631
    

命令详解

  1. 语法

    awk options 'pattern {action }' input-file > output-file
    
    pattern 表示匹配规则,action表示动作,action一般为打印print
    example:
    awk '{print $1,$4}' netstat.txt
    awk -F: '{print $1,$4}' netstat.txt // -F 表示指定分割符为:,默认是空格或tab
    awk '/tcp/ {print $1,$4}' netstat.txt // 打印出包含字符tcp的行
    
  2. 内建变量

    变量描述
    $0当前记录(这个变量中存放着整个行的内容)
    1   1~ 1 n当前记录的第n个字段,字段间由FS分隔
    FS输入字段分隔符 默认是空格或Tab,FS是field separator的缩写
    NF当前记录中的字段个数,就是有多少列,number of field的索写
    NR已经读出的记录数,就是行号,从1开始,如果有多个文件话,这个值也是不断累加中。nubmer of record的缩写
    FNR当前记录数,与NR不同的是,这个值会是各个文件自己的行号
    RS输入的记录分隔符, 默认为换行符,record separator的缩写
    OFS输出字段分隔符, 默认也是空格 output field separator的缩写
    ORS输出的记录分隔符,默认为换行符 output record separator的缩写
    FILENAME当前输入文件的名字
  3. 如何使用

    1. 打印出有7个字段的列

      awk '{NF==7} {print}' netstat.txt 
      
    2. 打印总共有几条记录

      awk 'END{print NR}' netstat.txt
      
    3. 带行号输出内容

      awk '{print NR,$0}' netstat.txt
      
    4. 冒号为字段分隔符,打印出行数,第一列内容,字段数和字段分隔符

      awk -F: '{print NR,$1,"NF="NF,"FS="FS}' /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
      adm:x:3:4:adm:/var/adm:/sbin/nologin
      lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
      sync:x:5:0:sync:/sbin:/bin/sync
      执行命令之后
      1 root NF=7 FS=:
      2 bin NF=7 FS=:
      3 daemon NF=7 FS=:
      4 adm NF=7 FS=:
      5 lp NF=7 FS=:
      6 sync NF=7 FS=:
      7 shutdown NF=7 FS=
      
    5. 通过指定输出的分隔符为逗号,可以导出csv文件

      awk 'BEGIN{FS=":";OFS=","} {print $1,$2,$3,$4,$5,$6,$7}' /etc/passwd > passwd.csv 
      
  4. BEGIN 和 END

    1. awk的通常格式为

      awk 'BEGIN{最开始执行,只执行一次} {在begin之后执行,每一行都会执行一次} END{最后执行,只执行一次} 
      
    2. 例子

      新建一个文件myscript,写入下面的脚本

      BEGIN {
      print "Users and thier corresponding home"
      print " UserName \t HomePath"
      print "___________ \t __________"
      FS=":"
      }
      {
      print $1 "  \t  " $6
      }
      END {
      print "The end"
      }
      

      通过-f 指定awk脚本

      awk -f myscript  /etc/passwd
      
      结果为
      Users and thier corresponding home
       UserName 	 HomePath
      ___________ 	 __________
      root  	  /root
      bin  	  /bin
      daemon  	  /sbin
      adm  	  /var/adm
      lp  	  /var/spool/lpd
      sync  	  /sbin
      shutdown  	  /sbin
      halt  	  /sbin
      The end
      

    高级用法

    1. 字符串匹配

      # //是模式,表示这是一个正则表达式的匹配
      awk '/LISTEN/' netstat.txt
      
      ## 格式为 exp ~/regexp/ 表示匹配第一个字段中有udp的记录
      awk '$1 ~ /udp/' netstat.txt
      
      ## 格式为 exp !~/regexp/ 表示匹配第一个字段中没有udp的记录
      awk '$1 !~/udp/' netstat.txt
      
      #exp ~/regexp和exp !~/regexp/可以用在if,while,for,do中做判断条件
      awk '{ if ($1 ~ /udp/) print }' netstat.txt
      awk '{ if ($1 !~ /udp/) print }' netstat.txt
      
    2. 内置函数

      awk中可以使用shell中的内置函数

      # 输出字段的长度
      awk '{print $1 " length is " length($1)}' netstat.txt
      tcp length is 3
      tcp length is 3
      tcp length is 3
      tcp length is 3
      tcp length is 3
      tcp length is 3
      tcp length is 3
      tcp length is 3
      # 转成大写
      awk '{print $1 " upper is " toupper($1)}' netstat.txt
      tcp upper is TCP
      tcp upper is TCP
      tcp upper is TCP
      tcp upper is TCP
      tcp upper is TCP
      tcp upper is TCP
      tcp upper is TCP
      tcp upper is TCP
      udp upper is UDP
      

    参考资料

    1. 内建变量,参看:http://www.gnu.org/software/gawk/manual/gawk.html#Built_002din-Variables

    2. 流控方面,参看:http://www.gnu.org/software/gawk/manual/gawk.html#Statements

    3. 内建函数,参看:http://www.gnu.org/software/gawk/manual/gawk.html#Built_002din

    4. 正则表达式,参看:http://www.gnu.org/software/gawk/manual/gawk.html#Regexp

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值