AWK

GNU awk

全称:Aho,Weiberger,Kernighan,是三个作者的名字,所以简称为awk

awk:报告生成器,主要用来格式化文本输出的,它能够实现在处理文本文件时对文档中的字段有条件的显示,而且将显示的结果用非常美观的文本形式给予输出。我们所用的awk其实就是gawk,他是一个符号链接指向gawk的。

gawk – pattern scanning and processing language:模式扫描及处理语言

  awk其实就是一个解释器,是一个编程语言的解释器,从本质上来讲他也是一个编程语言,支持条件判断、数组、循环等各种各样一个编程语言当中几乎所有的功能。因此我们又可以把gawk称为一个脚本语言解释器,他所支持的是一个单独的脚本编程语言的功能。和bash编程语言一样,也是过程式编程语言。另外gawk也有自己内置的变量,允许用户自定义变量。

awk的基本用法:

awk [options] 'program' FILE ...
    paogram的组成:PATTERN{ACTION STAEMRNTS(动作语句)}:可以有多个语句,语句之间用分号分割。

    选项:
        -F:指明输入时用到的字段分隔符:从文件中读取数据时以什么当作分割符
        -v var=varlaue:用于实现自定义变量:

awk常用的输出命令:

1、print

print item1,item2,...
    要点:
        (1)逗号分隔符:
        (2)输出的各item可以是字符串,也可以是数值,也可以是当前记录的字段,变量或awk的表达式
        (3)如省略item,相当于print $0(打印整行)

2、变量

内建变量
        FS:input field seperator:输入字段分隔符,默认为空白字符
        OFS:output field seperator:输出字段分隔符,默认为空白字符
        RS:input record seperator:输入时的换行符
        ORS:output record seperator:输出时的换行符
        NF:number of field:每一行的字段数量
            {print NF},{print $NF}
        NR:num of record:行数
        FNR:各文件分别计数:行数
        FILENAME:当前文件名
        ARGC:命令行参数的个数
        ARGV:是一个数组,保存的是命令行所给定的各参数
自定义变量   
        (1)-v var=value
            变量名区分字符大小写:
        (2)在program中直接定义

3、printf

格式化输出:printf FORMAT,item1,item2,...
        (1)FORMAT必须给出
        (2)不会自动换行,需要显示给出换行控制符,\n
        (3)FORMAT中需要分别为后面的每个intem指定一个格式化符号
            格式符:
                %c:显示字符的ASCII码
                %d,%i:显示十进制整数
                %e,$E:科学计数法数值显示
                %f:显示为浮点数
                %g,%G:以科学计数法或浮点形式显示数值
                %s:显示字符串
                %u:无符号整数
                %%:显示%号自身 
            修饰符:
                #[.#]:第一个数字控制显示的宽度:第二个#显示小数点后的精度:
                -:左对齐
                +:显示数值的符号

4、操作符

算术操作符:
        x+y,x-y,x*y,x/y,x^y,x%y
        -x
        +x:转换为数值:
    字符串操作符:没有符号的操作符,字符串连接的意思
赋值操作符:
        =,+=,-=,*=,/=,%=,^=
        ++,--
比较操作符:
        >,>=,<,<=,!=,==
模式匹配符:
        ~:是否匹配
        !~:是否不匹配
逻辑操作符:
        &&,||,!
函数调用:
        function_name(argu1,argu2,...)
条件表达式:
        selector?if-true-expression:if-fales-expressiion
        示例:格式化显示/etc/passwd文件中用户名是普通用户还是系统用户还是管理员
        awk -F: '{$3>=500?usertype="Common User":usertype="Sysadmin or Sysuser";printf "%15s:%-s\n",$1,usertype}' /etc/passwd

5、pattern

(1)empty:空模式,匹配每一行
(2)/regular expression/:仅处理能够被此处模式匹配到的行
(3)relational expression:关系表达式:结果有“真”有“假”,结果为“真”才会被处理;
    真:结果为非0值为真,非空字符串也为真
(4)line ranges:行范围,指明起始行,指明结束行
    startline,endline:/pat1/,/pat2/
    注意:不支持直接给出数字的格式,须使用如下格式
    示例:显示/etc/passwd中第2行到第10行的用户名
    ~]# awk -F: '(NR>=2&&NR<=10){print $1}' /etc/passwd
(5)BENGIN/END模式
    BENGIN{}:仅在开始处理文件中的文本之前执行一次:
    END{}:仅在文本处理完成之后执行一次

6、常用的action

(1)Expressions:表达式
(2)Control statements:控制语句,if,while,for等
(3)Compound statemens:组合语句
(4)input statemens:输入语句
(5)output statemens:输出语句

7、控制语句

if(condition) {statmens}
if(condition) {statmens} else {statemens}
while(condition) {statmens}
do {statmens} while(condition)
for(expr1;expr2;expr3) {statemens}
break
continue
delete arrar[index]
delete array
exit
{ statements}

控制语句说明
    (1)if-else
    语法:if(condition) statement [else statement]
    ~]# awk -F: '{if($3>=500) {printf "Common user: %s\n",$1} else {printf "root or Sysuser: %s\n",$1}}' /etc/passwd
    ~]# awk -F: '{if($NF=="/bin/bash") print $1}' /etc/passwd
    示例:显示/etc/fstab文件中字段数大于5的行
    ~]# awk '{if(NF>5) print $0}' /etc/fstab
    示例:显示当前使用空间大于20的设备名称
    ~]# df -h | awk -F[%] '/^\/dev/{print $1}' |awk '{if($NF>=20) print $1}'
    使用场景:对awk取得的整行或某个字段做条件判断
    (2)while循环
    语法:while(condition) statemnt
        条件为真进入循环:条件为假退出循环
    使用场景:对一行内的多个字段逐一类似处理时使用:对数组中的各元素逐一处理时使用:

    ~]# awk '/^[[:space:]]*linux16/{i=1;while(i<=NF) {print $i,length($i); i++}}' /etc/grub2.cfg
    ~]# awk '/^[[:space:]]*linux16/{i=1;while(i<=NF) {if(length($i)>=7) {print $i,length($i); i++}}' /etc/grub2.cfg
    (3)do-while循环
    语法:do statement while(condition)
        意义:至少执行一次循环体
    (4)for循环
    语法:for(expr1;expr2;expr3) statement
        for(variable assignment;conditiion;iteration process) {for-body}
        ~]# awk '/^[[:space:]]*llinux16/{for(i=1;i<=NF;i++) {print $i,length($i)}}' /etc/grub2.cfg
        特殊用法:
            能够遍历数组中的元素:
            语法:for(var in array) {for-body}
    (5)switch语句
    语法:switch(expression) {case VALUE1 or /REGEXP/: statement;case VALUE2 or /REGEXP2/: statement;...;default: statement}
    (6)break和continue
        break [n]
        continue
    (7)next
        提前结束对本行的处理而直接进入下一行
    示例:显示ID号为偶数的用户
    ~]# awk -F: '{if($3%2!=0) next; print $1,$3}' /etc/passwd

8、array

关联数组:array[index-expression]
    index-expreesion
        (1)可使用任意字符串;字符串要使用双引号
        (2)如果某数组元素事先不存在,在引用时,awk会自动创建此元素,并将其值初始化为“空串”
            如要判断数组中是否存在某元素,要使用“index in array”格式进行
            weekdays["mon"]="Monday"
            如要遍历数组中的每个元素,要使用for循环
                for(var in  array) {for-boby}
                ~]# awk 'BEGIN{weekdays["mon"]="Monday";weekdays["tue"]="tuesday";for(i in weekdays) {print weekdays[i]}}'
            注意:var会遍历array的每个索引
                示例:显示各端口的状态次数
                ~]# netstat -tan | awk '/^tcp\>/{state[$NF]++}END{for(i in state) { print i,state[i]}}'
                示例:显示每个ip地址访问httpd服务的次数
                ~]# 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
            练习2:统计指定文件中每个单词出现的次数;
                ~]# awk '{for(i=1;i<=NF;i++){count[$i]++}}END{for(i in count) {print i,count[i]}}' /etc/fstab

9、函数

(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]}}'
(2)自定义函数
练习:

显示/etc/fstab文件后五行的第2和第4个字段

]# tail -5 /etc/fstab  |awk '{print $2,$4}'

显示/etc/fstab文件后五行的第2和第4个字段,并且在输出的行首显示“ali”字符,在行尾显示数字“1”。

]# tail -5 /etc/fstab |awk '{print "ali",$2,$4,1}'

显示/etc/passwd文件中的第1个字段,要求awk内建变量输入分割符为冒号

]# awk -v FS=':' '{print $1}' /etc/passwd

使用冒号为分割符显示/etc/passwd文件中的用户名

]# awk -F: '{print $1}' /etc/passwd

使用输入分隔符为冒号和输出分隔符为冒号显示/etc/passwd文件的第1,3,7字段(以冒号为分割符显示/etc/passwd中用户名,UID,shell类型)

]# awk -F':' -v OFS=':' '{print $1,$3,$7}' /etc/passwd

以空格为属入换行符显示/etc/passwd文件

]# awk -v RS=' ' '{print }' /etc/passwd

显示/etc/fstab文件中每行的字段数

]# awk '{print NF}' /etc/fstab

显示/etc/passwd文件中每行的最后一个字段

]# cat /etc/passwd |awk -F':' '{print $NF}'

分别显示/etc/fstab和/etc/issue文件的行数

]# awk '{print FNR}' /etc/fstab /etc/issue

格式化显示/etc/passwd文件中每行的用户名,UID,shell类型,要求对应显示username,uid,shelltype

]# awk -F: '{printf "username: %s, uid: %d, shelltype: %s \n",$1,$3,$7}' /etc/passwd

格式化显示/etc/passwd文件中每行的用户名,UID,shell类型,要求对应显示username,uid,shelltype,并且格式输出宽度为15个字符,左对齐。

]# awk -F: '{printf "username: %-15s, uid: %-15d, shelltype: %-15s \n",$1,$3,$7}' /etc/passwd

显示/etc/fstab文件中以UUID开头的行

]# awk '/^UUID/{print }' /etc/fstab

显示/etc/fstab文件中不以UUID开头的行

]# awk '!/^UUID/{print }' /etc/fstab

显示UID大于500的用户名和UID

]# awk -F: '$3>=500{print $1,$3}' /etc/passwd
]# awk -F: '{if($3>=500)print $1,$3}' /etc/passwd

显示shell类型为bash的用户

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

原创文章,作者:M20-1马星,如若转载,请注明出处:http://www.178linux.com/48725

(0)
上一篇 2016-09-23 15:41
下一篇 2016-09-23 15:50

相关推荐

  • mysql慢查询日志进行按库切割重写文件然后分析

    需求: 把每天的慢查询日志进行按库切割 对每个库的慢查询日志进行分析 思路: 工具/功能 一般统计信息 高级统计信息 脚本 优势 mysqldumpslow 支持 不支持 perl mysql官方自带 mysqlsla 支持 支持 perl 功能强大,数据报表齐全,定制化能力强. mysql-explain-slow-log 支持 不支持 perl 无 my…

    Linux干货 2015-04-03
  • centos 7 修改sshd服务默认端口号

    由于最近sshd服务默认端口号22被匿名进行试探性的进行登入,为防止匿名用户再次进行试探性的登入,将sshd服务的默认端口号进行修改。 环境:centos 7.3  xshell 思路:先将sshd的被指文件进行修改,把sshd服务的默认端口号修改为所需要的端口号,然后重启sshd服务,发现重启报错。找其原因是应为selinux不允许自定义sshd…

    Linux干货 2017-04-06
  • mount中-o的选项利用

        Mount下—-o 选项的各项用处  mount-o 选项 sync,async 同步模式,异步模式(defaults)         此选项的默认模式为异步模式。在同步模式下,内存的任何修改都会实时的同步到硬盘当中,这种模式的…

    2017-08-19
  • 计划任务

              前要:Linux的计划任务主要分为三块。单一的执行一次计划任务,系统自动的选择空闲时间去执行特定的任务, 周期性的执行相关任务,下面就此三块做简要的描述。 一:单一的计划任务at      &nbsp…

    2017-07-01
  • 网络管理2

    一、知识整理 1、网卡配置文件格式:vim /etc/sysconfig/network-scripts/ifcfg-eth0 TYPE=Ethernet接口类型,常见的类型有Ethernet,Bridge BOOTPROTO=static设置静态还是DHCP获取IP,static和none都为静态,不写此行必须指定。查看配置DHCP之后的信息: cat /…

    Linux干货 2016-09-07
  • 处理交换文件和分区

    处理交换文件和分区 交换分区是系统RAM的补充   基本设置包括:  1 创建交换分区或者文件  2 使用mkswap写入特殊签名  3 在/etc/fstab文件中添加适当的条目  4 使用swapon -a 激活交换空间 挂载交换分区  启用:swapon swapon [OPTION]……

    Linux干货 2016-09-01