十五、shell编程三剑客(4)awk

1.简介

  awk是一种编程语言,用于在linux/unix下对文本和数据进行处理。数据可以来自标准输入、一个或多个文件,其他命令的或命令的输出。它支持用户自定义函数和动态正则表达式等先进功能。

  awk的处理文本和数据方式是逐行处理,从第一行到最后一行。寻找匹配的特定模式的行,并在这些行上进行你想要的操作。如果没有指定处理动作,则把匹配的行显示到标准输出(屏幕)。

 

2.工作原理

  

 

  (1)awk 使用一行作为输出,并将这一行赋值给内部变量$0,每一行也可以称为一个记录,以换行符结束

  (2)然后,行被:(默认为空格或者制表符)分解成字段(或域),每一个字段储存在对应的编号的变量中,从$1开始,最多100个字段

  (3)awk输出之后,将从文件中获取另一行,并将其存储在$0中,覆盖原来的内容,然后将新的字符串分割成字段并进行处理,该过程将持续到所有行处理完毕。

  

 

 

  自定义分隔符

  awk -F:  '{print $1,$5}' /erc/passwd | head -3

  

 

 

3.语法

  awk   选项   '命令'   文件名

 

  command(命令):

    分为过去,现在,将来

    BEGIN{}  {}  END{}

  BEGIN{}:发生在行处理之前

  {}:行处理时,读一行执行一次

  END{}:行处理后

  

 

 

4.内部变量

  FS  输入字段分隔符(默认空格)

  

 

    在开始之前把:赋值给FS,FS即使内部变量

 

  OFS  输出字段分隔符

  

 

    重新给结果分割

 

  RS  输入记录(行)分隔符,默认换行符,就是行与行之间的分隔符(了解)

  

 

    把空格当成分隔符

 

  ORS  输出记录(行)分隔符,默认换行符

  

 

 

  FNR  多文件独立编号  同下

  

 

 

  NR  多文件汇总编号

  

 

 

  NF  显示列

  

 

   如果$NF等于输出最后一列,因为这里等于print $5

  

 

 

5.格式化输出print

  

 

 

6.模式(正则表达)和动作

  字符串比较

    awk '/^root/' /etc/passwd  以root开头的那行

    awk '$0 - /^root/' /etc/passwd  像是以root开头的

    awk '$0 !~ /^root/passwd'  不像是以root开头的

    awk -F: '$1 ~ /^root/' /etc/passwd  在第一行中像是以root开头的

 

  关系运算符

    语法 x>y

    awk -F: '$3>5' /etc/passwd

    awk -F: '$3 == 3' /etc/passwd

    awk -F: '$3*10 < 100' /etc/passwd

 

  多条件-逻辑操作符和复合模式  

  与  &&

  awk -F: '$1 ~ /root/ && $3<=5' /etc/passwd

  或  ||

  awk -F: '$1 ~ /root/ || $3<=5' /etc/passwd

  非  !

  

  多条件-范围模式

  awk '/从哪里/,/到哪里/' filename

  例子

  awk -F: '/adm/,/mail/' /etc/passwd  从adm那行到mail那行显示出来,注意避免匹配重复的字段

 

7.awk脚本编程

  变量

  awk调用变量

  awk -v user=root -F: '$1 == user' /etc/passwd  -v定义变量

  

 

   外部变量

  

 

    因为$name不是内部变量,需要用''括起来,但是单引号里面套单引号是有问题的,所以要用""双引号套起来

 

  条件&判断

    if语句

      if(条件测试){执行语句}

    示例1

      需求:如果$3是0,就说他是管理员

      awk -F: '{if($3==0){print $1 "是管理员"}}' /etc/passwd

      awk -F: '{if($3==0){print $1 "是管理员"}else{print $1 "是普通用户"}}' /etc/passwd

      

     示例2

      需求:统计管理员和系统用户的数量

      awk -F: '{if($3==0){r++}else{u++}}END{print "管理员个数:"r;print"系统用户数:"u}' /etc/passwd

       

 

     示例3

      统计三种用户的数量

      显示出三种用户信息,管理员:管理员ID为0,内置用户:用户ID<1000,普通用户:用户ID>999

      awk -F: '{if($3==0){a++}else if($3>999){b++}else{c++}}END{print "管理员:"a;print "内置用户:"b;print "普通用户:"c}' /etc/passwd

      

 

      awk -F: '{if($3==0){print $1 "是管理员"}else if($3>999){print $1 "是内置用户"}else{print $1 "是普通用户"}}' /etc/passwd

      

 

 

  循环

    示例1:循环打印10个数字

      awk 'BEGIN{while(){}}'

      

 

 

    示例2:第一行打印十次

      awk -F: '{while(i<=9){print $0;i++}}' passwd

      

 

 

   for

    示例1:循环打印5个数字

      awk 'BEGIN{for(i=1;i<=5;i++){print i}}'

      

 

 

    示例2:将每行打印10次

       awk -F: '{for(i=1;i<=10;i++){print $0}}' passwd

      

 

 

    示例3:打印每一行的第一列

      awk -F: '{for(i=1;i<=NF;i++){print $1}}' passwd

 

  数组

    定义数组

    需求:将用户名定义为数组的值,打印第一个值

    awk -F: '{username[i++]=$1}END{print username[0]}' passwd

    

 

      打印所有值

    

 

       

       awk默认不排序,填上索引再以数字排序就行

 

8.awk编程案例

  需求:统计/etc/passwd中各种类型shell的数量

  awk -F: '{shellname[$NF]++}END{for(i in shellname){print i "有" shellname[i] "个"}}' /etc/passwd

  

 

posted @   真渡  阅读(78)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 2025年我用 Compose 写了一个 Todo App
· 张高兴的大模型开发实战:(一)使用 Selenium 进行网页爬虫
点击右上角即可分享
微信分享提示