Linux教程

linux三剑客之awk +for循环+while循环

本文主要是介绍linux三剑客之awk +for循环+while循环,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

for循环

        格式:
          方式一:
            for 变量 in 数组
            do      # for循环开始
                    
                    # for循环体
            
            done    # for循环结束  
          方式二:
            for 变量 in 数组 ; do for循环体1; for循环体2; for循环体3 ; done
        
        作用:
        
            1、作用是遍历数组,对数组中的所有元素进行处理
            2、将数组中存储的元素取出来使用(计算,做特殊处理)
            
        案例:
        
            循环出数组
            
                for i in ${array7[*]}
                do
                    
                    echo $i
                
                done
    
                [root@localhost ~]# for i in ${array7[*]}; do echo $i; echo "xxxx" ; done

awk

awk基础

1、什么是awk,主要作用是什么?
    
    awk 主要用来处理文件,将文本按照指定的格式输出。其中包含变量,循环以及数组。
    
2、awk的格式
​
    awk [选项] '匹配规则和处理规则' [处理文本路径]
        [root@localhost ~]# awk -F: '{print $1}' /etc/passwd
    
    标准输出 | awk [选项] '匹配规则和处理规则' 
        [root@localhost ~]# cat /etc/passwd | awk -F: '{print $1}'
        
        
    匹配规则:
    
        1、字符串
        2、正则表达式
        
    处理规则:
    
        BEGIN{}     : BEGIN是在awk处理文本之前运行
        //          : 使用的匹配规则
        {}          :循环(每次只处理一行数据)
        END{}       :当所有的处理全部执行完毕之后,执行END中的相关操作

案例

    案例:
    
        案例1:把/etc/passwd中的包含root的行打印出来
            [root@localhost ~]# awk -F: '/root/' /etc/passwd
            root:x:0:0:root:/root:/bin/bash
            operator:x:11:0:operator:/root:/sbin/nologin
            
        案例2:把/etc/passwd中以root开头的行打印出来
            [root@localhost ~]# awk -F: '/^root/' /etc/passwd
            root:x:0:0:root:/root:/bin/bash
​
        案例3:将/etc/passwd中匹配第三列和第五列的数据
            
            [root@localhost ~]# awk -F: '{print $5,$3}' /etc/passwd
            
        案例4:打印以root或者ntp开头的行的解析器
        
            [root@localhost ~]# awk -F: '/^root|^ntp/{print $7}' /etc/passwd
            [root@localhost ~]# awk -F: '/^(root|ntp)/{print $7}' /etc/passwd

awk的工作原理

    (1)awk会接收一行作为输入,并将这一行赋给awk的内部变量$0,每一行也可称为一个记录,行的边界是以换行符作为结束(表明:awk是一行一行的去处理文本的)
    (2)然后,刚刚读入的行被以:为分隔符分解成若干字段(或域),每个字段存储在已编号的变量中,编号从$1开始,最多达100个字段
    注意:如果未指定行分隔符,awk将使用内置变量FS的值作为默认的行分隔符,FS默认值为空格,如果说要指定分隔符,需要使用-F参数或者重新定义FS变量
    (3)使用print函数打印,如果$1$3之间没有逗号,它俩在输出时将贴在一起,应该在$1,$3之间加逗号,该逗号与awk的内置变量OFS保持一致,OFS默认为空格,于是以空格为分隔符输出$1和$3
    我们可以指定:awk -F: 'BEGIN{OFS="-"}{print $1,$3}' /etc/passwd
     
    (4)输出之后,将从文件中获取另一行,然后覆盖给$0,继续(2)的步骤将该行内容分隔成字段。。。继续(3)的步骤
    该过程一直持续到所有行处理完毕

awk中的变量

    $0: 表示文本中的所有字段
    NR: 记录号(行号)
    NF: 保存记录的字段数,$1,$2...$100(最后一列)
    FS: 输入字段分隔符,默认空格
    OFS:输出字段分隔符

案例

案例:
    
        案例1:输出/etc/passwd中的所有内容包括行号。
            [root@localhost ~]# awk -F: '{print NR,$0}' /etc/passwd
        
        案例2:要求把第7行之后的内容输出出来,包括行号。
            [root@localhost ~]# awk -F: 'NR > 7{print NR,$0}' /etc/passwd
            
        案例3:要求输出第7行之后的内容且第14行之前的内容输出出来,包含行号
            [root@localhost ~]# awk -F: 'NR > 7 && NR < 14{print NR,$0}' /etc/passwd
        
        案例4:由案例3,要求输出每行的UID增加1
            [root@localhost ~]# awk -F: 'NR>7&&NR<14{print $3,$3+1}' /etc/passwd
        
        案例5:要求输出倒数第3列
            [root@localhost ~]# awk -F: '{print $(NF-2)}' /etc/passwd
        
        案例6:要求不使用-F参数,以:分割,并输出第3列和第5列
            [root@localhost ~]# awk 'BEGIN{FS=":"}{print $5,$3}' /etc/passwd
            
        案例7:要求实验证明-F 和 FS的优先级
        
            [root@localhost ~]# awk -F/ 'BEGIN{FS=":"}{print $7,$3}' /etc/passwd
            
            证明得出-F参数的优先级小于FS变量的优先级
        
        案例8:要求以:分割,并输出第3列和第5列,第三列和第五列之间使用+号分割
            [root@localhost ~]# awk -F: 'BEGIN{OFS="+"}{print $3,$5}' /etc/passwd
​
            注:所有的变量的定义都应该放在BEGIN里面
        
        案例9:将/etc/nginx/nginx.conf中的所有的词的个数

格式化输出

​
​
    ================print函数===================
    date | awk '{print "月:",$2,"\n年:",$1}'
    月: 09月 
    年: 2020年
     
    awk -F: '{print "用户名:",$1,"用户id:",$3}' /etc/passwd
     
    ================printf函数===================
    awk -F: '{printf "用户名:%s 用户id:%s\n",$1,$3}' /etc/passwd
    awk -F: '{printf "|%-15s| %-10s| %-15s|\n", $1,$2,$3}' /etc/passwd
​
    %s 字符类型
    %d 数值类型
    占15格的字符串
    - 表示左对齐,默认是右对齐
    printf默认不会在行尾自动换行,加\n

案例

    案例:
    
        案例1:要求输出第1列和最后一列,排版整齐
            [root@localhost ~]# awk -F: '{printf "%-16s %s \n",$1,$NF}' /etc/passwd
            

操作模式

    1、正则模式
    
        awk -F: '/^xxx/' /etc/passwd
    
    2、比较模式
    
        > < 
        
        awk -F 'NR > 7' /etc/passwd
    
    3、条件模式
​
        awk -F 'NR > 7' /etc/passwd
    
    4、算数运算
    
        awk -F '{print $3,$3+1}' /etc/passwd 
    
    5、范围模式
        
        [root@localhost ~]# awk -F: '/root/,/ftp/{print $1}' /etc/passwd

流程控制

if判断
    
        单分支
            if () {}
        
        双分支
            if () {} else {}
        
        多分支
            if(){} else if() {} else{}
    
        案例:
        
            案例1:打印奇数行的数据
                [root@localhost ~]# awk -F: '{if( NR % 2 ){print NR,$0}}' /etc/passwd
                
            案例2:打印偶数行的数据
                [root@localhost ~]# awk -F: '{if( NR % 2 == 0 ){print NR,$0}}' /etc/passwd
                [root@localhost ~]# awk -F: 'NR%2==0{print $0}' /etc/passwd
    
                注:单分支情况下是可以省略if,多分支情况下不能省略
            
            案例3:要求打印出偶数行中的包含bash的行
                [root@localhost ~]# awk -F: '/bash/{if(NR%2==0){print NR,$0}}' /etc/passwd
​
            案例4:要求在奇数行前输出奇数,偶数行前输出偶数
                [root@localhost ~]# awk -F: '{if(NR%2){printf "奇数行:%s\n",$0}else{printf "偶数行:%s\n",$0}}' /etc/passwd
            
            案例5:在前7行前加7, 前14行前加14,其他原样输出
                [root@localhost ~]# awk -F: '{if(NR<=7){printf "7 %s \n",$0}else if (NR<=14){printf "14 %s \n",$0}else{print $0}}' /etc/passwd

for循环+awk

    for循环
    
        for (变量 in 数组) {语句}
        
        for (变量;条件;表达式){语句}
    
        知识储备:
        
            ++ : 每次加1
            -- : 每次减1
    
        案例:
        
            案例1:要求统计以#开头的行中包含的词的格式
​
                [root@localhost ~]# egrep '^ *#' /etc/fstab | egrep -o "[a-zA-Z0-9]+" | awk '{arr[$1]++}END{for(i in arr){printf "%-20s %d\n",i,arr[i]}}'
​
            案例2:输入一个文件路径,要求打印出它的数字权限(不允许使用stat)
            
                [root@localhost ~]# ll [路径] | awk 'BEGIN{FS=""}{if($2=="r"){u=u+4} if($3=="w"){u=u+2} if($4=="x"){u=u+1} if($5=="r"){g=g+4} if($6=="w"){g=g+2} if($7=="x"){g=g+1} if($8=="r"){o=o+4} if($9=="w"){o=o+2} if($10=="x"){o=o+1}}END{print u,g,o}'

 

while循环

while循环
    
        while(判断条件) {}
        
        案例1:把/etc/passwd中的每一行都重复打印3遍
            [root@kubernetes ~]# awk -F: '{i=0;while(i<3){print $0;i++}}' /etc/passwd
            
        案例2:统计/etc/passwd中每个解析器的用户数
            [root@kubernetes ~]# awk -F: '{arr[$NF]++}END{for(i in arr){print i,arr[i]}}' /etc/passwd
                    
        案例3:要求把/etc/passwd中第10行的中每一列都打印出来   
            operator:x:11:0:operator:/root:/sbin/nologin
            
            operator
            x 

            
            [root@kubernetes ~]# awk -F: 'NR==10{i=0;while(i<=NF){print $i;i++}}' /etc/passwd

 

这篇关于linux三剑客之awk +for循环+while循环的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!