• Linux三剑客:awk的高级用法


    目录

    awk高级用法

    awk控制语句—if-else判断

    awk控制语句—while循环

    awk控制语句—do-while循环

    awk控制语句—for循环

    shell脚本中较相似的控制语句

    break和continue

    next

    awk数组

    awk自定义函数

    awk中调用shell 命令


    这一篇主要介绍awk的高级用法,因为awk可以单独作为一门语言来使用,所以它有很多高级用法

    awk高级用法

    awk控制语句—if-else判断

    (1)语法

    1. if(condition){statement;…}[else statement] 双分支
    2. if(condition1){statement1}else if(condition2){statement2}else{statement3} 多分支

    (2)使用场景:对awk 取得的整行或某个字段做条件判断

    (3)演示

    演示文本awkdemo内容:

    1. hello:world
    2. linux:redhat:lalala:hahaha
    3. along:love:youou

    ---打印出了如果/etc/passwd下的第三个字段即uid大于3小于1000的第1列和第3列 

    1. [root@centos111 test]# awk -F: '{if($3>10 &&$3<1000)print $1,$3}' /etc/passwd
    2. operator 11
    3. games 12
    4. ...

    ---打印出如果最后一列是"bin/bash"的则打印出第一列和最后一列 

    1. [root@centos111 test]# awk -F: '{if($NF=="/bin/bash")print $1,$NF}' /etc/passwd
    2. root /bin/bash
    3. amandabackup /bin/bash
    4. user /bin/bash
    5. user1 /bin/bash
    6. user2 /bin/bash

    ---输出总列数大于3的行 

    1. [root@centos111 test]# awk -F: '{if(NF>3) print $0}' awkdemo
    2. linux:redhat:lalala:hahaha

    ---第3列>=1000为Common user,反之是root or Sysuser 

    1. [root@centos111 test]# awk -F: '{if($3>=1000){printf "Conmmon user:%s\n",$1} else{printf "root or Sysuser:%s\n",$1}}' /etc/passwd
    2. root or Sysuser:root
    3. ...
    4. Conmmon user:nfsnobody
    5. ...

     ---磁盘利用率超过40的设备名和利用率

    1. [root@centos111 test]# df -h|awk -F% '/^\/dev/{print $1}'|awk '$NF > 40{print $1,$NF}'
    2. /dev/mapper/centos-root 56

    ---test=100和>90为very good; 90>test>60为good; test<60为no pass 

    1. [root@centos111 test]# awk 'BEGIN{ test=100;if(test>90){print "very good"}else if(test>60){ print "good"}else{print "no pass"}}'
    2. very good
    3. [root@centos111 test]# awk 'BEGIN{ test=80;if(test>90){print "very good"}else if(test>60){ print "good"}else{print "no pass"}}'
    4. good
    5. [root@centos111 test]# awk 'BEGIN{ test=50;if(test>90){print "very good"}else if(test>60){ print "good"}else{print "no pass"}}'
    6. no pass

    awk控制语句—while循环

    (1)语法

    while``(condition){statement;…}

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

    (2)使用场景

      对一行内的多个字段逐一类似处理时使用

      对数组中的各元素逐一处理时使用

    (3)演示

    ---以along开头的行,以:为分隔,显示每一行的每个单词和其长度

    1. [root@centos111 test]# awk -F: '/^along/{i=1;while(i<=NF){print $i,length($i); i++}}' awkdemo
    2. along 5
    3. love 4
    4. youou 5

    ---以:为分隔,显示每一行的长度大于6的单词和其长度 

    1. [root@centos111 test]# awk -F: '{i=1;while(i<=NF) {if(length($i)>=6){print $i,length($i)}; i++}}' awkdemo
    2. redhat 6
    3. lalala 6
    4. hahaha 6

    ---计算1+2+3+...+100=5050

    1. [root@centos111 test]# awk 'BEGIN{i=1;sum=0;while(i<=100){sum+=i;i++};print sum}' 5050
    2. 5050

    awk控制语句—do-while循环

    1)语法

    do` `{statement;…}``while``(condition)

    意义:无论真假,至少执行一次循环体

    (2)计算1+2+3+...+100=5050

    1. [root@centos111 test]# awk 'BEGIN{sum=0;i=1;do{sum+=i;i++}while(i<=100);print sum}'
    2. 5050

    awk控制语句—for循环

    (1)语法

    for``(expr1;expr2;expr3) {statement;…}

    (2)特殊用法:遍历数组中的元素

    for``(var ``in` `array) {``for``-body}

    (3)演示

    ---显示每一行的每个单词和其长度

    1. [root@centos111 test]# awk -F: '{for(i=1;i
    2. hello 5
    3. linux 5
    4. redhat 6
    5. lalala 6
    6. along 5
    7. love 4
    8. //NF表示字段数量,

    ---求男m、女各自的平均

    1. [root@along ~]# cat sort.txt
    2. xiaoming m 90
    3. xiaohong f 93
    4. xiaohei m 80
    5. xiaofang f 99
    6. [root@centos111 test]# awk '{m[$2]++;score[$2]+=$3}END{for(i in m) {printf "%s:%6.2f\n",i,score[i]/m[i]}}' sort.txt 
    7. m: 85.00
    8. f: 96.00

    shell脚本中较相似的控制语句

    break和continue

    1. ---奇数相加
    2. [root@centos111 test]# awk 'BEGIN{sum=0;for(i=1;i<=100;i++){if(i%2==0)continue;sum+=i}print sum}'
    3. 2500
    4. ---1+2+...+66
    5. [root@centos111 test]# awk 'BEGIN{sum=0;for(i=1;i<=100;i++){if(i==66)break;sum+=i}print sum}'
    6. 2145
    7. ---奇数相加``
    8. [root@centos111 test]# awk 'BEGIN{sum=0;for(i=1;i<=100;i++){if(i%2==0)continue;sum+=i}print sum}'
    9. 2500
    10. ---1+2+...+66``
    11. [root@centos111 test]# awk 'BEGIN{sum=0;for(i=1;i<=100;i++){if(i==66)break;sum+=i}print sum}'
    12. 2145

    next

    next:提前结束对本行处理而直接进入下一行处理(awk 自身循环)

    ---只打印偶数行

    1. [root@centos111 test]# awk -F: '{if(NR%2!=0) next; print $1,$3}' /etc/passwd
    2. bin 1
    3. adm 3
    4. ...

    awk数组

    关联数组:array[index-expression]

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

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

    (3)若要判断数组中是否存在某元素,要使用“index in array”格式进行遍历

    (4)若要遍历数组中的每个元素,要使用for 循环:for(var in array) {for-body}

    演示

    1. [root@centos111 test]# cat awkdemo2
    2. aaa
    3. bbbb
    4. aaa
    5. 123
    6. 123
    7. 123

    ---去除重复的行

    1. [root@centos111 test]# awk '!arr[$0]++' awkdemo2
    2. aaa
    3. bbbb
    4. 123

    ---打印文件内容,和该行重复第几次出现

    1. [root@centos111 test]# awk '{!arr[$0]++;print $0,arr[$0]}' awkdemo2
    2. aaa 1
    3. bbbb 1
    4. aaa 2
    5. 123 1
    6. 123 2
    7. 123 3

    分析:把每行作为下标,第一次进来,相当于print ias...一样结果为空,打印空,!取反结果为1,打印本行,并且++变为不空,下次进来相同的行就是相同的下标,本来上次的值,!取反为空,不打印,++变为不空,所以每次重复进来的行都不打印

    (2)数组遍历

    1. [root@centos111 test]# awk 'BEGIN{abc["ceo"]="along";abc["coo"]="mayun";abc["cto"]="mahuateng";for(i in abc){print i,abc[i]}}'coo mayun
    2. ceo along
    3. cto mahuateng
    4. [root@centos111 test]# awk '{for(i=1;i<=NF;i++)abc[$i]++}END{for(j in abc)print j,abc[j]}' awkdemo2
    5. aaa 2
    6. bbbb 1
    7. 123 3

    数值\字符串处理

    (1)数值处理

    • rand():返回0和1之间一个随机数,需有个种子 srand(),没有种子,一直输出0.237788

    演示:

    1. [root@centos111 test]# awk 'BEGIN{print rand()}'
    2. 0.237788
    3. [root@centos111 test]# awk 'BEGIN{srand();print rand()}'
    4. 0.973507
    5. [root@centos111 test]# awk 'BEGIN{srand();print rand()}'
    6. 0.70811
    7. ---取0-50随机数
    8. [root@centos111 test]# awk 'BEGIN{srand();print int(rand()*100%50)+1}'
    9. 4
    10. [root@centos111 test]# awk 'BEGIN{srand();print int(rand()*100%50)+1}'
    11. 28

    (2)字符串处理:

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

    • sub(r,s,[t]) :对t 字符串进行搜索r 表示的模式匹配的内容,并将第一个匹配的内容替换为s

    • gsub(r,s,[t]) :对t 字符串进行搜索r 表示的模式匹配的内容,并全部替换为s 所表示的内容

    • plit(s,array,[r]) :以r 为分隔符,切割字符串s ,并将切割后的结果保存至array 所表示的数组中,第一个索引值为1, 第二个索引值为2,…

    演示:

    1. [root@centos111 test]# echo "2008:08:08 08:08:08" | awk 'sub(/:/,"-",$1)'
    2. 2008-08:08 08:08:08
    3. //搜索第一个值然后替换
    4. [root@centos111 test]# echo "2008:08:08 08:08:08" | awk 'gsub(/:/,"-",$1)'
    5. 2008-08-08 08:08:08
    6. 搜索所有的值进行替换
    7. [root@centos111 test]# echo "2008:08:08 08:08:08" | awk '{split($0,i,":")}END{for(n in i){print n,i[n]}}'
    8. 4 08
    9. 5 08
    10. 1 2008
    11. 2 08
    12. 3 08 08

    awk自定义函数

    (1)格式:和bash区别:定义函数()中需加参数,return返回值不是$?,是相当于echo输出

    1. function name ( parameter, parameter, ... ) {
    2.   statements
    3.   return expression
    4. }

    (2)演示

    1. [root@centos111 test]# cat fun.awk
    2. function max(v1,v2) {
    3. v1>v2?var=v1:var=v2
    4. return var
    5. }
    6. BEGIN{a=3;b=2;print max(a,b)}
    7. [root@centos111 test]# awk -f fun.awk
    8. 3

    awk中调用shell 命令

    (1)system 命令

      空格是awk 中的字符串连接符,如果system中需要使用awk中的变量可以使用空格分隔,或者说除了awk 的变量外其他一律用"" 引用 起来。

    1. [root@centos111 test]# awk BEGIN'{system("hostname")}'
    2. centos111

    (2)向awk脚本传递参数

    ① 格式:

    awkfile var=value var2=value2... Inputfile

    注意 :在BEGIN 过程 中不可用。直到 首行输入完成以后,变量才可用 。可以通过-v 参数,让awk 在执行BEGIN 之前得到变量的值。命令行中每一个指定的变量都需要一个-v

    ② 示例

    1. [root@centos111 test]# cat test.awk
    2. #!/bin/awk -f
    3. {if($3 >=min && $3<=max)print $1,$3}
    4. [root@centos111 test]# chmod +x test.awk
    5. [root@centos111 test]# ./test.awk -F: min=100 max=200 /etc/passwd
    6. systemd-network 192
  • 相关阅读:
    Vue+Element之SpingBoot学生管理系统
    MySQL的故事——MySQL架构与历史
    Windows程序相同程序实现运行互斥
    LeetCode·106.从中序与后序遍历序列构造二叉树·递归
    C语言--结构体(内容超级详细)
    input子系统上报事件讲解(以重力传感器lis2dw12驱动为例)
    最新AI系统ChatGPT源码+AI绘画系统源码+支持GPT4.0+Midjourney绘画+搭建部署教程+附源码
    ScaleFlux CSD 2000 在携程的应用实践
    【JavaSE】文件与IO流
    ESP8266教程5 — MCU和机智云APP之间互相通信
  • 原文地址:https://blog.csdn.net/qq_68163788/article/details/134459740