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)
上一篇 2016-06-24 21:31
下一篇 2016-06-26 09:23

相关推荐

  • DNS and BIND 进阶

    主DNS服务器的ip地址:192.168.1.109 主DNS服务器主机名:bogon 正向区域名:sh.com 反向区域名:1.168.192.in-addr.arpa 正向区域文件名称:/var/named/sh.com.hosts 反向区域文件名称:/var/named/192.168.1.rev 配置主文件/etc/named.conf过程 1、编辑…

    Linux干货 2016-12-06
  • Ansible安装及简单使用

    简介: ansible是新出现的自动化运维工具,基于Python开发,集合了众多运维工具(puppet、cfengine、chef、func、fabric)的优点,实现了批量系统配置、批量程序部署、批量运行命令等功能。ansible是基于模块工作的,本身没有批量部署的能力。真正具有批量部署的是ansible所运行的模块,ansible只是提供一种框架。主要包…

    Linux干货 2016-08-07
  • 路漫漫其修远兮第十周

    1、请详细描述CentOS系统的启动流程(详细到每个过程系统做了哪些事情) 从dawning大湿兄那里借来的图,如下: 启动过程 (PC架构) POST –> Boot Sequence(BIOS) –> Boot Loader (MBR)–>GRUB—> Kernel(ramdisk) &#821…

    Linux干货 2017-02-24
  • N29 第一周作业

    1、描述计算机的组成及其功能。
    2、按系列罗列Linux的发行版,并描述不同发行版之间的联系与区别。
    3、描述Linux的哲学思想,并按照自己的理解对其进行解释性描述。
    4、说明Linux系统上命令的使用格式;详细介绍ifconfig、echo、tty、startx、export、pwd、history、shutdown、poweroff、reboot、hwclock、date命令的使用,并配合相应的示例来阐述。
    5、如何在Linux系统上获取命令的帮助信息,请详细列出,并描述man文档的章节是如何划分的。
    6、请罗列Linux发行版的基础目录名称命名法则及功用规定

    Linux干货 2018-03-05