awk笔记

gawk - pattern scanning and processing language

报告生成器,可进行格式化输出,文本处理三剑客之一,是基于sed和grep功能的扩展

一般用法格式:

awk [options] 'program' FILE...
    program: /regular/{print}

语句之间用分号分隔
   print,printf

选项:

-F:指明输入时用到的字段
   -v var=value:指明自定变量

awk运作方式:

逐行读入文本,并将每个字段给予一个变量进行存储,$1..$NF ,而$0标识一整行
   显示文本的的2,4字段,默认是空格为分隔符,默认输出以空格为分隔符

tail -3 /etc/fstab  | awk '{print $2,$4}'

1.print item1,item2...

        以逗号作为分隔符
        变量的引用,不允许在""内部
        省略item,则默认print $0

2.变量

1.内键变量

FS:input field seperator指明输入字段分隔符类似-F
               OFS:output field seprator 指明输出字段分隔符
               RS:input record seperator输入时的换行符

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

ORS:output record seperator输出时的换行符
               NF:number of field,每行的字段数量
                   $NF:最后一个字段
               NR:number of record,行数
               FNR:各文件分别计数
               FILENAME:当前的文件名
               ARGC:命令行参数的个数(program 不为参数)

                ]# awk 'BEGIN{print ARGC}' /etc/fstab

ARGV:数组,保存,命令行中所给定的每个字段

2.自定义变量

-v var=value
                   变量名区分大小写

                ]# awk -v test='hello gawk' 'BEGIN{print test}

在program中直接定义

                ]# awk 'BEGIN{test="hello gawk";print test}'

3.printf命令:格式化输出

        printf "FORMAT1,FORMAT2",item1,item2... ===>FORMAT与item对应位置的格式化
            1.FORMAT是必须要给出
            2.printf不自动换行,显式给出换行符\n
            2.FORMAT需要分别为后面的每个item指定一个格式化符号
格式符(需用双引号):
                    %c :显示字符的ASCII码
                    %d %i:显示十进制整数
                    %e %E:科学计数法数值显示
                    %f:显示浮点数
                    %g,%G:以科学计数法或浮点数显示数值
                    %s:显示字符串
                    %u:无符号整数
                    %%:显示%自身

格式化输出示例:

            ]# awk -F: '{printf "Username: %s\n",$1}' /etc/passwd
修饰符:加在格式符之前,用于控制格式符的显示方式

#.#  第一个数字控制显示宽度;第二个#表示小数点后的精度

                       %3.2f
                    - : 显示为左对齐
                    + : 显示数值的符号,有正数负数之分

示例:

            ]# awk -v FS=':' '{printf "username: %-25s,UDI: %-25d\n",$1,$3}' /etc/passwd

4.操作符

算术操作符

            x+y,x-y,x*y,x^y,x/y,x%y
            -x:正数转化为负数
            +x:字符串转化为数值

字符串操作符:没有符号的操作符,字符串的连接

        赋值操作符:
            =,+=,-=,*=,/=,%=,^=
            ++,--
        比较操作符:
            >,<,>=,<=,!=,==
        模式匹配符:
            ~:是否匹配
            !~:是否不匹配
        逻辑操作符:
            &&
            ||
            !

函数调用:

            function_name(argu1,argu2,...)
        条件表达式:(三目运算)
            selctor?if-true-expression:if-false-expression

示例:查找本机的普通用户及系统用户

                # awk -F: -v OFS=":"  '{$3>1000?usertype="common user":usertype="system user";printf "%-18s,%s\n",$1,usertype}' /etc/passwd

5.PATTERN

1 .empty:空模式,匹配每一行

2 ./regular expression/:文本过滤仅处理被模式匹配到的行

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

3 .relatinal expression:关系表达式:结果为真式,才会被处理;非零为真

            ]# awk -F:  '$3>=1000{print $1,$3}' /etc/passwd

查找其用户的默认shell为/bin/bash的用户

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

4 .lines ranges:行范围
           startline,endline
               注意:不支持直接指定数字,可以容如下方式

            ]# awk -F: '(NR>=2&&NR<=5){print $1,$2}' /etc/passwd
        /part1/,/part2/
            ]# awk -F: '/^h/,/^9/{print $1}' /etc/passwd

5 .BEGIN/END模式:处理开始之前处理一次
           BEGIN{}:仅在开始处理文件中的文件之前执行一次:
           END{}:仅在文本处理完成之后执行一次

        ]# awk -F: 'BEGIN{print "username uid \n----------"}{print $1,$3' /etc/passwd

6 .常用的action:

        1.expressions
        2.control statements:if ,while,等;
        3.compound statements:组合语句;
        4.input statements
        5.output statements

7 .控制语句

        if(condition) {statements} else {statments}
        while(condition) {statements}
        for(expr1;expr2;expr3) {statements}
        {statements}组合语句需要{}
  1. if-else

    语法: if(condition) statements [else statements]

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

    取得磁盘利用率:

         ]# df -h| awk -F [%] '/^\/dev/{print $1}'|awk '{if($NF>=10) print $1}'
  2. while循环:

    语法:while(condition) statements

    条件为"真",进入循环;条件为假则退出循环
    使用场景:对一行内的多个字段逐一处理,对数组中的字段做逐一处理

    函数:length()字符长度

    统计每个字段的长度?

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

    并统计出大于7的字段?

           ~]# 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)
               意义:先执行循环语句,而后在判断执行while循环
  4. for循环:

    语法:for(expr1;expr2;expr3) statement
    for(variable assignment;condition;iteration proccess) {for-body}

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

    特殊用法:
    能够遍历数组中的元素:

                   for(var in array) {for-body}

for(var in array) {for-body}

    ~]# awk 'BEGIN{weekdays["mon"]="monday";weekdays["tue"]="tuesday";for(i in weekdays) {print weekdays[i]}}'
        注意:var会遍历array的每个索引;

查看netstat -nat中tcp状态出现的次数?

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

查看ss -nat中tcp状态出现的次数?

        ~]# ss -tan |awk '{state[$1]++}END{for(i in state) {print i,state[i]}}'

统计/etc/fstab中文件系统的个数?

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

统计指定文件中每个单词出现的次数?

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

8.内置函数:

        数值处理:
            rand():返回指定字符串的长度;
        字符处理:
            length([s]):返回指定字符串的长度;
            sub(r,s,[t]):以r表示模式查找t所表示的字符中匹配的内容,并将其第一次出现替换为s所表示的内容;
            gsub(r,s,[t]):以r表示模式查找t所表示的字符中匹配的内容,并将全局出现替换为s所表示的内容;
            splits(s,a[,r]):以r为分隔符切割字符s,并将切割后的结果保存至a所代表的的数组中

统计ip地址出现的次数?

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