• Lniux学习-AWK使用


    AWK

    AWK 与 sed 的区别

    • AWK用于比较规范的文本处理,用于统计数量并输出指定字段
    • sed 用于将不规范的文本,处理为比较规范的文本

    AWK的字段引用和分离

    • AWK也是按行读取,每行称作记录,使用空格、制表符分隔开的单词称作字段,可以自己指定分隔符来隔开字段。
    • 使用$1 $2 ... $n 表示每一个字段,$0 表示一整行
      • awk '{print $1,$2,$3}' filename
      • awk -F "'" '/^menu/{ print $2 }' /boot/grub2/grub.cfg 以'号进行分割字段,取出文件中的内核信息
      • { print x++,$2 } x++ 可以显示行数
    • -F 选项用于指定分隔符
      • awk -F ',' '{print $1,$2,$3}' filename
      • 分隔符可以使用正则表达式表示

    AWK的表达式

    • 系统变量
      • FS 和 OFS 字段分隔符,OFS 表示输出的字段分隔符

        • head -5 /etc/passwd | awk 'BEGIN{FS=":"}{ print $1 }'
          BEGING,在读入文件之前,进行预处理。在读入passwd文件之前,就通过FS选项指定好了以“:”作为分隔符。
        • head -5 /etc/passwd | awk 'BEGIN{FS=":";OFS="-"}{ print $1,$2 }' OFS="-",OFS是在查找到字段后,系统是默认使用空格进行隔开,而OFS改变了默认隔开的符号。
      • RS 行记录分隔符,记录行,RS 默认就是一个换行符,在多行合并成单行时,使用RS进行处理

        • head -5 /etc/passwd | awk 'BEGIN{RS=":"}{ print $1 }' 系统默认的行记录分隔符是换行符,RS=":",把行记录分隔符换成:
      • NR 和 FNR 行数

        • head -5 /etc/passwd | awk '{ print NR,$0 }' NR显示行号,$0显示行内容
        • awk '{ print NR,$0 }' /etc/hosts /etc/hosts
        • awk '{ print FNR,$0 }' /etc/hosts /etc/hosts
          对单个文件,使用NR和FNR没什么区别,若是接多个文件,NR会按顺序对内容一直排序,不区分文件;FNR是以先文件进行区分,再各自进行排序。
      • NF 字段数量,最后一个字段内容可以用 $NF 取出

        • head -5 /etc/passwd | awk 'BEGIN{FS=":"}{ print NF }' 输出每一行中有多少个字段

    AWK 的条件和循环语句

    条件语句格式:
    If(表达式)

    awk语句1

    [ else

    awk语句2

    ]

    若有多个语句需要执行可以使用{}将多个语句括起来

    例如:kpi.txt
    user1 88 28 34 34 44
    user2 45 55 22 33 66

    • awk '{if($2>=80) print $1}' kpi.txt
    • awk '{if($2>=80) {print $1 ; print $2} }' kpi.txt

    循环语句

    • while 循环格式

    while(表达式)

    awk 语句1

    • do 循环格式

    do{

    awk 语句1

    } while(表达式)

    • for 循环格式

    for{初始值;循环判断条件:累加}

    awk 语句1

    • head -1 kpi.txt | awk '{for(c=2;c<=NF;c++) sum+=$c;print $sum}' kpi.txt 计算第一行的kpi总值
    • head -1 kpi.txt | awk '{for(c=2;c<=NF;c++) sum+=$c;print sum/(NF-1)}' kpi.txt 计算第一行的kpi平均值
    • awk '{sum=0; for(c=2;c<=NF;c++) sum+=$c;print sum/(NF-1)}' kpi.txt 计算所有行各自的kpi平均值

    AWK 数组

    数组:一组具有某种关联的数据,可通过下标依次访问

    • 数组名[下标]=值
    • 下标可用数字或字符串表示

    查看数组所有元素

    • for( 变量 in 数组名 )
      使用 数组名[变量],依次对每个数组的元素进行操作

    • awk '{sum=0; for(c=2;c<=NF;c++) sum+=$c;avg[$1]=sum/(NF-1)} END { for(user in avg) sum12+=avg[user];print sum2/NR}' kpi.txt 计算所有人各自的平均值后,再计算总的平均值

    • awk的脚本文件以.awk结尾,加载awk脚本文件:awk -f avg.awk kpi.txt

    删除数组
    - delete 数组名[下标]

    命令行参数数组

    • ARGC:awk 后面所带的命令行参数的个数
    • ARGV:具体每一个参数的内容

    demo:
    demo.awk 内容

    BEGIN{
    
        for (x=0;x<ARGC;x++)
            print ARGV[x]
            print ARGC
    }
    

    执行: awk -f demo.awk 11 22 33

    awk 数据功能的使用

    Demo:
    统计得分的总数和平均分

    score1 99 44 55 66 42
    score2 90 45 67 89 32
    score3 34 43 65 65 36
    score4 45 76 34 34 56

    {
    sum = 0
    for( c=2; c<=NF; c++)
    	# sum,每个人的总得分
    	sum+=$c  
    
    # avg,每个人的平均得分,NF 表示分隔的字段总数
    avg[$1] = sum / ( NF-1 ) 
    
    # 设置等级
    if ( avg[$1] >= 80 )
    	letter = "S"
    else if ( avg[$1] >= 70 ) 
    	letter = "A"
    else if( avg[$1] >= 60 )
    	letter = "B"
    else
    	letter = "C"
    
    # 输出每个人的平均得分和等级
    print $1,avg[$1],letter
    
    # 计算相同等级的有多少个,这种方法可以使用在统计某一个IP使用的次数,某一个时间发生的次数这些场景中
    letter_all[letter]++	
    
    }
    END{
    for ( user in avg)
    	# 计算所有平均值的总数
    	sum_all += avg[user] 
    
    # 计算总的平均得分,NR表示行数
    avg_all = sum_all / NR
    print "average all",avg_all
    
    # 计算在总的平均值之下和之上各自有几个
    for (user in avg)
    	if ( avg[user] > avg_all )
    		above++
    	else
    		below++
    
    print "above",above
    print "below",below
    
    print "S:",letter_all["S"]
    print "A:",letter_all["A"]
    print "B:",letter_all["B"]
    print "C:",letter_all["C"]
    
    }
  • 相关阅读:
    day16_包(Package)丶API丶JavaBean
    day12_类中成员之方法
    day18_面向对象的三大特征之多态
    day14_面向对象的三大特征之继承
    react记录
    如何使用Houdini进行程序化优化?
    程序员健康指南
    uniapp 自定义导航
    uniapp :uviewui
    markdown
  • 原文地址:https://www.cnblogs.com/chenri/p/12735256.html
Copyright © 2020-2023  润新知