awk的进阶

前言

awk的中有很多的控制语句,awk也支持if语句,while语句,for语句等等编程逻辑充的控制语句及数组、函数。

awk的进阶无非就是多练。

1.控制语句

(1)if-else语句

语句格式: if(condition) {statments}    if  (条件) 条件为真 执行{statments}

只有一个语句可以省略{}。组合语句必须加{}if(condition) {statments} else {statements}双分支语句     if(条件)为真时执行{statments} else否则执行{statrments}

例:显示系统上某个用户的ID号大于1000,这是普通用户,反之则为系统用户

~]# awk  -F:  '{if($3>=1000) {printf "Common user: %s\n",$1} else {printf "root or Sysuser: %s\n",$1}}' /etc/passwd

(提示:  -F: 是以:为分隔符     $3/etc/passwd 是第三段      printf 格式化输出     $1/etc/passwd 的第一段    另外这是空模式是每一行都读取的)

87bb3ed5-1473-42be-8794-d4fea51e022e.png

例   显示shell为/bin/bash的用户  

~]# awk -F: '{if($NF=="/bin/bash") print $1}' /etc/passwd

  (   提示NF是字段数   -F:分隔符:)

265bbfa1-6b88-40ce-84e6-9f44f7e0a9b5.png

显示/etc/fstab 的一行字段数大于五个 ,否则不显示

~]# awk '{if(NF>5) print $0}' /etc/fstab

(提示:NF是字段数    $本身 也就是取过来的行整行)

ddd5de5b-5ba0-4dfa-a0d4-34a7eff78ce0.png

显示磁盘使用的使用率到5%的分区。

~]# df -h | awk -F[%] '/^\/dev/{print $1}' | awk '{if($NF>=5) print $1}'

  (提示: -F[%]是以空格分隔   /^\/dev/ 是以/dev/开头 也就是地址定界。     $NF是取末尾的字段数)   

956b120d-d125-459f-afce-af2cc4fb8e22.png

对awk取得的整行或某个字段做条件判断;

(2) while循环

语法:while(condition) statement

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

while(conditon) {statments} 只有一个语句可以省略{}。组合语句必须加{}

while使用场景:对一行内的多个字段逐一类似处理时使用;对数组中的各元素逐一处理时使用;

  显示每一个符合条件的行,行内的每一个字段,字段本身和字段的个数。条件(统计/etc/grub,conf  以空白开头后跟kernel的行)

 awk '/^[[:space:]]*kernel/{i=1;while(i<=NF) {print $i,length($i); i++}}' /etc/grub.conf 

 (提示: /^[[::space:]]*kernel/  以有多个空白的行后跟kernel做地址定界   i=1:知道变量i=1 i<=NF是判断有多少个字段数 NF是字段数,print $i 是显示第几个字段数 , length()内建函数 :返回指定字符串的长度; i++自加 不然都是1了

cea8bba2-01b5-436f-8be1-f51f9b4eae00.png

把字符数小于7的不予显示

awk '/^[[:space:]]*kernel/{i=1;while(i<=NF) {if(length($i)>=7){print $i,length($i)}; i++}}' /etc/grub.conf 

(3)do-while循环

语法:do statement while(condition)

意义:不管是真是假先执行一遍。至少执行一次循环体

(4) for循环

    语法: for(expr1;expr2;expr3) {statements}

                                expr1  初始化;expr2条件判断;expr3控制变量不断的修正

                                 for(variable assignment;condition;iteration process) {for-body}

                          ~]# awk '/^[[:space:]]*kernel/{for(i=1;i<=NF;i++) {print $i,length($i)}}' /etc/grub2.cfg

显示每一个符合条件的行,行内的每一个字段,字段本身和字段的个数。条件(统计/etc/grub,conf  以空白开头后跟kernel的行)(跟上面差不多 ,只不过是采用for循环)

                         

cd9c4964-f7dc-44da-a15b-45e8dc02e0f0.png

特殊用法:

能够遍历数组中的元素;

语法:for(var in array) {for-body}

(5) switch语句

语法:switch(expression) {case VALUE1 or /REGEXP/: statement; case VALUE2 or /REGEXP2/: statement; …; default: statement}

    这个语法意思: 表达式: case  value1 值跟表达式匹配  或者是  正则表达式跟表达式匹配。则显示statment 。。。。。。。默认用default:statement

        

(6) break和continue

break [n]  跳出N层循环

continue  退出本次循环

   

(7)next

提前结束对本行的处理而直接进入下一行;这是跟break不一样的 ,next直接进入下一行的,break是进入下一字段的。

                                   显示ID为偶数的用户

                          awk -F: '{if($3%2!=0) next; print $1,$3}' /etc/passwd

                      (提示  $3%2!=0   next ID号不等于0  直接跳入下一行  )

 

e94e1d0d-84dc-4cb6-8dee-d717d8aa4e79.png

2.array(数组)

关联数组:array[index-expression]在awk 使用最多

                                index-expression:

                       delete array[index]  从数组中删除某个元素

delete array   删除整个数组

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

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

                                                 若要判断数组中是否存在某元素,要使用"index in array"格式进行;

                                                                             weekdays[mon]="Monday"

                   例:              awk 'BEGIN{weekdays["mon"]="Monday";weekdays["tue"]="Tuesday";print weekdays["mon"]}

                                          它会显示那个呢;  你在去掉mon  和tue的双引号  看看会怎么言   

     若要遍历数组中的每个元素,要使用for循环;

for(var in array) {for-body}

  例:awk 'BEGIN{weekdays["mon"]="Monday";weekdays["tue"]="Tuesday";for(i in weekdays) {print weekdays[i]}}'

                   (提示: 定义一个数组weekdays )

       

532b2d50-6dd3-4c51-8d94-bbdf94479c59.png

注意:var会遍历array的每个索引;

state["LISTEN"]++

state["ESTABLISHED"]++

                                         显示netstat -tan 的以tcp开头的状态,并做统计     

~]# netstat -tan | awk '/^tcp\>/{state[$NF]++}END{for(i in state) { print i,state[i]}}'

                                           (提示:  '/tcp\>/做地址定界, state[]数组 )

a2813579-c704-41fa-a71e-ecf6230cbbed.png

~]#awk '{ip[$1]++}END{for(i in ip) {print i,ip[i]}}' /var/log/httpd/access_log

练习1:统计/etc/fstab文件中每个文件系统类型出现的次数;

~]# awk '/^UUID/{fs[$3]++}END{for(i in fs) {print i,fs[i]}}' /etc/fstab

                                           (提示:‘/^UUID’地址定界    fs[]数组 )

2448ba63-b264-4c17-b01a-59f78e21670d.png

练习2:统计指定文件中每个单词出现的次数;

~]# awk '{for(i=1;i<=NF;i++){count[$i]++}}END{for(i in count) {print i,count[i]}}' /etc/fstab

                                                 (提示 :count[]是数组 )

f0f541bd-4e2c-4a9b-a481-a18170aa5739.png

3.函数

(1)内置函数

数值处理:

rand():返回0和1之间一个随机数;

字符串处理:

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

sub(r,s,[t]):以r表示的模式来查找t所表示的字符中的匹配的内容,并将其第一次出现替换为s所表示的内容;

gsub(r,s,[t]):以r表示的模式来查找t所表示的字符中的匹配的内容,并将其所有出现均替换为s所表示的内容;

split(s,a[,r]):以r为分隔符切割字符s,并将切割后的结果保存至a所表示的数组中;


~]# netstat -tan | awk '/^tcp\>/{split($5,ip,":");count[ip[1]]++}END{for (i in count) {print i,count[i]}}'    

  

92cce50f-6696-40cc-9ada-e2b237ab88e8.png

           

(2)自定义函数

想加强sed和awk可以看《sed和awk》

原创文章,作者:N19_king,如若转载,请注明出处:http://www.178linux.com/20275

(0)
N19_kingN19_king
上一篇 2016-06-24 21:31
下一篇 2016-06-26 09:23

相关推荐

  • 软链接和硬链接的区别

    Linux链接概念 Linux链接分两种,一种被称为硬链接(Hard Link),另一种被称为符号链接(Symbolic Link)。 硬链接 硬连接指通过索引节点来进行连接。在Linux的文件系统中,保存在磁盘分区中的文件不管是什么类型都给它分配一个编号,称为索引节点号(Inode Index)。在Linux中,多个文件名指向同一索引节点是存在的。一般这种…

    Linux干货 2016-10-29
  • 搭建私有CA服务器

       CA(Certificate Authority)证书颁发机构主要负责证书的颁发、管理以及归档和吊销。证书内包含了拥有证书者的姓名、地址、电子邮件帐号、公钥、证书有效期、发放证书的CA、CA的数字签名等信息。证书主要有三大功能:加密、签名、身份验证。下面来看一下自建CA的过程    一、建立CA服务器 &nbsp…

    Linux干货 2016-03-14
  • Linux运维学习历程-第三天-初识Linux

    初识Linux 本章内容    初安装Linus的网络配置    防火墙的关闭    用户    终端    shell    命令纪要 安装linux之后,linux默认网卡开机不是自动激活,并且防火墙开启的,这对初期我们学习linux会…

    Linux干货 2016-08-03
  • 搭建缓存功能的WEB服务集群

    搭建缓存功能的WEB服务集群 实验简介 本文主要介绍双主模型的nginx proxy高可用集群的搭建方式。实验环境: 使用nfs服务器提供页面数据共享 使用单独的mariadb服务器提供关系型数据库 使用两台httpd服务器处理动态的php和静态页面资源 使用两台nginx服务器处理图片资源 使用两台varnish服务器作缓存处理 使用两台nginx作代理 …

    Linux干货 2017-07-15
  • 第三周作业

    1.列出当前系统上所有已经登录的用户的用户名,注意:同一个用户登录多次,则只显示一次即可。  2、取出最后登录到当前系统的用户的相关信息。  3、取出当前系统上被用户当作其默认shell的最多的那个shell。  4、将/etc/passwd中的第三个字段数值最大的后10个用户的信息全部改为大写后保存至/tmp/max…

    Linux干货 2016-12-21
  • N25_第五周作业

    1、显示当前系统上root、fedora或user1用户的默认shell [root@EASTED ~]# grep -E "(root|fedora|user1)" /etc/passwd root:x:0:0:root:/root:/bin/bash operator:x:11:0:o…

    Linux干货 2017-01-10