zoukankan      html  css  js  c++  java
  • 【操作系统之四】Linux常用命令之awk

    一、概念
    awk是一个报告生成器,拥有强大的文本格式化能力。
      数据可以来自标准输入(stdin)、一个或多个文件,或其它命令的输出;
      依次对每一行进行处理,然后输出;
      它在命令行中使用,但更多是作为脚本来使用。

    grep、sed、awk被称为Linux三剑客:
      grep适合单纯的查找或匹配文本;
      sed适合编辑匹配到的文本;
      awk适合格式化文本;

    二、awk命令格式

    awk [options] 'pattern{action}' file
    
    options参数有三个:-F指定分隔符,-f调用脚本,-v定义变量 var=value
    '' 引用代码块;
    pattern表示待匹配的模式;
    {action}表示一系列的动作命令;
    file表示等待操作的数据文件;

    三、内置变量
    1、分隔符
    FS : 输入字段分隔符(默认是任何空格)。

    [root@PCS101 ~]# cat test
    abc#123#dfhj#kfjda#kjd
    def#456#kjs#4sf#kks#09j
    [root@PCS101 ~]# awk '{print $1,$2}' test
    abc#123#dfhj#kfjda#kjd 
    def#456#kjs#4sf#kks#09j 
    [root@PCS101 ~]# awk -F# '{print $1,$2}' test
    abc 123
    def 456
    [root@PCS101 ~]# awk -v FS='#' '{print $1,$2}' test
    abc 123
    def 456

    OFS : 输出字段分隔符(默认值是一个空格)。

    [root@PCS101 ~]# awk -v FS='#' -v OFS='------' '{print $1,$2}' test
    abc------123
    def------456
    [root@PCS101 ~]# awk -v FS='#' -v OFS='------' '{print $1 $2}' test
    abc123
    def456

    2、NR和FNR

    NR : 表示记录数,在执行过程中对应于当前的行号
    FNR : 同NR ,但相对于当前文件,多文件记录不递增,每个文件都从1开始。

    [root@PCS101 ~]# cat t1.txt t2.txt
    abc def hij klm
    456 789 j2k tb3
    kkk djk zlm enjl
    fas 2d3 98s y67s 98sm
    [root@PCS101 ~]# awk '{print NR,$0}' t1.txt t2.txt
    1 abc def hij klm
    2 456 789 j2k tb3
    3 kkk djk zlm enjl
    4 fas 2d3 98s y67s 98sm
    [root@PCS101 ~]# awk '{print FNR,$0}' t1.txt t2.txt
    1 abc def hij klm
    2 456 789 j2k tb3
    1 kkk djk zlm enjl
    2 fas 2d3 98s y67s 98sm

    3、RS和ORS

    RS : 输入行分隔符, 默认为换行符

    [root@PCS101 ~]# awk -v RS=' ' '{print NR,$0}' t1.txt
    1 abc
    2 def
    3 hij
    4 klm
    456
    5 789
    6 j2k
    7 tb3
    
    [root@PCS101 ~]#

    ORS : 输出行分隔符,默认值是一个换行符

    [root@PCS101 ~]# awk -v ORS='+++' '{print NR,$0}' t1.txt
    1 abc def hij klm+++2 456 789 j2k tb3+++[root@PCS101 ~]#

    4、FILENAME
    FILENAME : 当前输入文件的名。

    [root@PCS101 ~]# awk '{print FILENAME,NR,$0}' t1.txt t2.txt
    t1.txt 1 abc def hij klm
    t1.txt 2 456 789 j2k tb3
    t2.txt 3 kkk djk zlm enjl
    t2.txt 4 fas 2d3 98s y67s 98sm
    [root@PCS101 ~]#

    5、ARGC和ARGV

    ARGC : 命令行参数的数目。
    ARGV : 包含命令行参数的数组。

    [root@PCS101 ~]# awk 'BEGIN{print "aaa",ARGV[0],ARGV[1],ARGV[2],ARGC}' t1.txt t2.txt
    aaa awk t1.txt t2.txt 3

    注意:ARGV[0]指不是'pattern{action}'

    6、自定义变量
    变量名区分大小写。
    方式一:

    [root@PCS101 ~]# awk -v myVar='testVar' 'BEGIN{print myVar}'
    testVar
    [root@PCS101 ~]# abc=666666
    [root@PCS101 ~]# awk -v newVar=$abc 'BEGIN{print newVar}'
    666666

    方式二:

    [root@PCS101 ~]# awk 'BEGIN{myvar=111;myvar2="222";print myvar,myvar2}'
    111 222

    其他内置变量:

    $n: 当前记录的第n个字段,比如n为1表示第一个字段,n为2表示第二个字段。
    $0 : 这个变量包含执行过程中当前行的文本内容。

    ARGIND : 命令行中当前文件的位置(从0开始算)。

    CONVFMT : 数字转换格式(默认值为%.6g)。
    ENVIRON : 环境变量关联数组。
    ERRNO : 最后一个系统错误的描述。
    FIELDWIDTHS : 字段宽度列表(用空格键分隔)。
    IGNORECASE : 如果为真,则进行忽略大小写的匹配。
    NF : 表示字段数,在执行过程中对应于当前的字段数。 print $NF对应一行中最后一个字段
    OFMT : 数字的输出格式(默认值是%.6g)。
    RSTART : 由match函数所匹配的字符串的第一个位置。
    RLENGTH : 由match函数所匹配的字符串的长度。
    SUBSEP : 数组下标分隔符(默认值是34)。
    print 是awk打印指定内容的主要命令,printf格式化输出命令。

    其他相关:

    制表符
    换行符
    ~ 匹配,与==相比不是精确比较
    !~ 不匹配,不精确比较
    + 匹配时表示1个或1个以上
    /[0-9][0-9]+/ 两个或两个以上数字
    /[0-9][0-9]*/ 一个或一个以上数字
    -F'[:#/]' 定义三个分隔符

    四、格式化输出
    使用格式化输出命令printf,默认不输出换行符。

    [root@PCS101 ~]# awk -F# '{printf "第一列:%s	 第二列:%s
    " ,$1,$2}' test
    第一列:abc    第二列:123
    第一列:def    第二列:456

    五、匹配
    就是在进行命令操作之前做的条件匹配,只有符合条件的行才被操作。
    1、BEGIN模式和END模式
    2、关系表达式模式
    可与逻辑运算符 (||, &&)一起使用

    [root@PCS101 ~]# awk 'NR==1 {print $0}' test
    abc#123#dfhj#kfjda#kjd

    3、正则模式

    awk '/正则表达式/{...}' file

    #查找以mysql开头的记录

    [root@PCS101 ~]# awk '/^mysql/{print $0}' /etc/passwd
    mysql:x:1002:1002::/home/mysql:/bin/bash

    4、行范围模式

    awk '/正则1/,/正则2/{...}' file

    从被正则1匹配的行开始到被正则2匹配的行结束,之间的所有行都会被执行后面的操作。

    六、动作
    所有动作的最外侧都必须有{}包裹起来。
    1、算术运算:(+,-,*,/,&,!,……,++,–)
    所有用作算术运算符进行操作时,操作数自动转为数值,所有非数值都变为0
    2、赋值运算:(=, +=, -=,*=,/=,%=,……=,**=)
    3、逻辑运算: (||, &&,!)
    4、关系运算:(<, <=, >,>=,!=, ==)
    5、正则运算:(~,~!)(匹配正则表达式,与不匹配正则表达式)
    6、三元运算:A ? B : C
    7、流程控制
    (1)条件分支控制

    [root@PCS101 ~]# awk '{if(NR==1) {print NR,NF}else if(NR==2){print NR,NF}}' test
    1 1
    2 1

    (2)循环控制

    #for循环语法格式1
    for(初始化; 布尔表达式; 更新) {
    //代码语句
    }
    [root@PCS101 ~]# awk 'BEGIN{for(i=1;i<=3;i++){print i}}'
    1
    2
    3
    
    #for循环语法格式2
    for(变量 in 数组) {
    //代码语句
    }
    
     
    #while循环语法
    while( 布尔表达式 ) {
    //代码语句
    }
    [root@PCS101 ~]# awk -v i=1 'BEGIN{while(i<=5){print i;i++}}'
    1
    2
    3
    4
    5
    
    #do...while循环语法
    do {
    //代码语句
    }while(条件)
    
    [root@PCS101 ~]# awk 'BEGIN{i=1;do{print i;i++}while(i<5)}'
    1
    2
    3
    4

    continue:结束本次循环;

    break:中断循环;

    exit:不再执行动作,也不是退出awk,而是转向执行END;

    [root@PCS101 ~]# awk 'BEGIN{print 1;exit;print 2;}{print "middle"}END{print "end"}'
    1
    end

    next:结束对当前行的处理,转而处理下一行

    [root@PCS101 ~]# cat t1.txt
    abc def hij klm
    456 789 j2k tb3
    [root@PCS101 ~]# awk '{if(NR==2){next};print $0}' t1.txt
    abc def hij klm

    七、数组

    数组是一个包含一系列元素的表.
    #将a定义为循环中的取值列表。从数组中取出的是数组的所有元素的下标

    [root@PCS101 ~]# awk 'BEGIN{a[0]="xiaohong";a[1]="xiaolan";for (i in a)print i;}'
    0
    1
    [root@PCS101 ~]#

    八、内置函数
    1、算数函数

    #rand是随机数函数,单独使用生成的值不变,需要配合srand使用,int截取整数部分
    [root@PCS101 ~]# awk 'BEGIN{print rand()}'
    0.237788
    [root@PCS101 ~]# awk 'BEGIN{print rand()}'
    0.237788
    [root@PCS101 ~]# awk 'BEGIN{srand();print rand()}'
    0.0534209
    [root@PCS101 ~]# awk 'BEGIN{srand();print rand()}'
    0.0632856
    [root@PCS101 ~]# awk 'BEGIN{srand();print int(100*rand())}'
    99

    2、字符串函数

    gsub sub 字符串替换函数
    index返回字符串出现的位置
    spilt切割

    3、其他函数
    asort()排序函数

    九、实际应用

    (1)计算/home目录下,普通文件的大小,使用KB作为单位
    [root@PCS101 ~]# ls -l|awk 'BEGIN{sum=0} !/^d/{sum+=$5} END{print "total size is:",int(sum/1024),"KB"}'
    total size is: 4450 KB
    (2)统计netstat -anp 状态为LISTEN和CONNECT的连接数量分别是多少
    [root@PCS101 ~]# netstat -anp|awk '$6~/LISTEN|CONNECTED/{sum[$6]++} END{for (i in sum) printf "%-10s %-6s %-3s 
    ", i," ",sum[i]}'
    LISTEN            12  
    CONNECTED         131
    
    (3)统计/home/cluster目录下不同用户的普通文件的总数是多少?
    [root@PCS101 cluster]# ls -l|awk 'NR!=1 && !/^d/{sum[$3]++} END{for (i in sum) printf "%-6s %-5s %-3s 
    ",i," ",sum[i]}' 
    cluster       4   
    root         2 
    
    统计/home/cluster目录下不同用户的普通文件的大小总size是多少?
    [root@PCS101 cluster]# ls -l|awk 'NR!=1 && !/^d/{sum[$3]+=$5} END{for (i in sum) printf "%-6s %-5s %-3s %-2s 
    ",i," ",sum[i]/1024/1024,"MB"}'
    cluster       111.849 MB 
    root         180.886 MB
     
    (4)输出成绩表
    [root@PCS101 ~]# cat test0
    Marry   2143 78 84 77
    Jack    2321 66 78 45
    Tom     2122 48 77 71
    Mike    2537 87 97 95
    Bob     2415 40 57 62
    [root@PCS101 ~]# awk 'BEGIN{math=0;eng=0;com=0;printf "Lineno.   Name    No.    Math   English   Computer    Total
    ";printf "------------------------------------------------------------
    "}{math+=$3; eng+=$4; com+=$5;printf "%-8s %-7s %-7s %-7s %-9s %-10s %-7s 
    ",NR,$1,$2,$3,$4,$5,$3+$4+$5} END{printf "------------------------------------------------------------
    ";printf "%-24s %-7s %-9s %-20s 
    ","Total:",math,eng,com;printf "%-24s %-7s %-9s %-20s 
    ","Avg:",math/NR,eng/NR,com/NR}' test0
    Lineno.   Name    No.    Math   English   Computer    Total
    ------------------------------------------------------------
    1        Marry   2143    78      84        77         239     
    2        Jack    2321    66      78        45         189     
    3        Tom     2122    48      77        71         196     
    4        Mike    2537    87      97        95         279     
    5        Bob     2415    40      57        62         159     
    ------------------------------------------------------------
    Total:                   319     393       350                  
    Avg:                     63.8    78.6      70 0


    参考:
    awk命令
    awk从入门到放弃
    AWK命令用法与举例

  • 相关阅读:
    冒泡排序
    linux常用命令
    Github上将公共仓库转为私有仓库or私有仓库转为共有仓库
    使用apt更新和升级系统软件
    Django用户认证模块中继承AbstractUser与AbstractBaseUser重写User表的区别
    详解django中的collectstatic命令以及STATIC_URL、STATIC_ROOT配置
    python入门指南
    python包装不上?国内网络问题,使用豆瓣源解决
    nginx入门
    Vue 实现页面刷新(provide 和 inject)
  • 原文地址:https://www.cnblogs.com/cac2020/p/11760615.html
Copyright © 2011-2022 走看看