zoukankan      html  css  js  c++  java
  • 文本处理三剑客之gawk

    gawk

    作者:Aho, Weinberger, Kernighan

    版本:

    • GNU awk:gawk
    • New awk:nawk

    简介:格式化文本输出工具,模式扫描及处理语言;报告生成器。

    用法:gawk  [  options  ]  '  PATTERN  {  ACTION  STATEMENTS  }'  FILE ...

    gawk [options] 'program' FILE ...

      program : PATTERN{ACTION STATEMENTS}

    1、选项(options)

    1.1:-f file:指定awk脚本文件

    1.2:-F : 输入数据时的字段分隔符

    1.3:-v var=value :自定义变量

    2、PATTERN

    1)空模式,匹配每一行

    2)/正则表达式/:仅处理被模式匹配到的行

    3)关系表示式(条件表示式):布尔值类型,结果为真(非0或非空字符串)则处理;结果为假(0或空字符串)则不处理

    4)地址定界;支持PATTERN和条件表达式;不支持数字直接定界

    5)BEGIN/END模式;BEGIN{}:仅在文本处理之前执行;END{}:仅在文本处理完成之后执行

    3、ACTIONS

    3.1、表达式

    1)三目表达式:selector?if-true-expression:if-false-expression

    如果selector为真,则执行if-true-expression;如果selector为假,则执行if-false-expression。

    3.2、控制语句

    1)if-else 语法:if(condition) statement [else statement]

    2)while 语法:while(condition) statement 条件真进入循环,条件假退出循环

    3)do-while 语法:do statement while(condittion) 先执行一次do,然后判断是否进入循环

    4)for 语法:for(variable assignment; condition; iteration process){for-body}

    *特殊用法:能够遍历数组中的元素,for(var in array) {for-body}

    5)switch 语法:switch(expression) {case VALUE1 or /PEGEXP/: statement; case VALUE2 or /PEGEXP2/: statement; ... ;default: statement}

    6)next:控制awk的内生循环,提前结束对本行的处理直接进入下一行

    7)continue | break | exit:退出循环,和shell中用法相同

    3.3、组合语句

    1)组合语句需要将多条语句放到大括号内

    3.4、输入语句

    3.5、输出语句

    3.5.1、print item1, item2, ... 输出命令

    1)逗号为分隔符

    2)输出的各item可以是字符串,也可是数值当前记录字段、变量或awk的表达式

    3)如果省略item,则相当于print $0

    3.5.2、printf FORMAT, item1, item2, ...:格式化输出命令

    1)FORMAT必须要给出

    2)不会自动换行,需要显示给出换行控制符,

    3)FORMAT中需要分别为后面的每个item指定一个格式化符号

    4)格式符

    • %c:显示字符的ASCII码;
    • %d,%i:显示十进制整数;
    • %e,%E:科学计数法数值显示;
    • %f:显示为浮点数;
    • %g,%G:以科学技术法或浮点数形式显示数值;
    • %s:显示字符串;
    • %u:无符号整数;
    • %%:显示%自身

    5)修饰符

    • M[.N]:M控制数组显示的宽度,N控制小数点的精度
    • -:左对齐显示,默认右对齐
    • +:显示数值的符号

    4、变量

    4.1、内建变量

    FS:输入字段分隔符,默认为空白字符

    OFS:输出字段分隔符,默认为空白字符

    RS:输入记录分隔符

    ORS:输出记录分隔符

    NF:字段数量;{print $NF}:表示最后字段值

    NR:行数,对不同文件行数累加计数

    FNR:行数,对不同文件行数分别计数

    FILENAME:显示当前文件名

    ARGC:命令行参数个数

    ARGV:数组,保存的是命令行中给定的各参数,使用ARGV[#]引用

    4.2、自定义变量

    1)-v var=value 在选项中定义

    2)在program中直接定义

    5、数组

    关联数组:array[index-expression]

    index-expression:

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

    2)如果某数组元素事先不存在,在引用时awk会自动创建此元素并将其值初始化为“空串”;若要判断数组中是否存在某元素,需要使用"index in array"格式进行;

    delete array[index]:删除数组中的单个元素

    delete array:删除整个数组

    6、函数

    6.1、内置函数

    srand():生成随机数种子

    rand():返回1和0之间的随机数(小数)

    int():对数取整

    length():返回指定字符串的长度

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

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

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

    system():在awk中调用shell命令,shell命令需要用双引号引起来,awk变量一定不能被双引号引起来

    6.2、自定义函数

    function name ( parameter1, parameter2, ... ) {
    statements
    return expression
    }

    7、awk中的操作符

    7.1、算术操作符:

    • +  -  *  /  ^  %
    • -x:整数转换为负数
    • +x:字符串转换为数值

    7.2、赋值操作符:

    • =  +=   -=   /=   %=   ^=   ++   --

    7.3、比较操作符:

    • >  <  >=  <=  !=  ==

    7.4、模式匹配符:

    • ~:左侧的字符串是否能够被右侧的模式匹配
    • !~:左侧的字符串是否能够被右侧的模式不匹配

    7.5、逻辑操作符:

    • && (并且)
    • ||    (或者)
    • !       (否)

    8、awk脚本

    格式:

    #!/bin/awk -f

    #this is a awk test script

    {ACTION  STATEMENTS}

    调用:

    test.awk  /path/file

    awk用法示例:

    1、从passwd文件中取出user,uid,shell

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

    2、从passwd文件中取出user,uid,shell并且以":"为分隔符输出

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

    3、以空格为换行符输出

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

    4、输出每行有多少个字段

    ~]# awk '{print NF}' /etc/passwd

    5、输出文件行号(有多少行)

    ~]# awk '{print NR}' /etc/passwd

    6、俩个文件分别打印行号

    ~]# awk -F: '{print FNR}' /etc/passwd /etc/fstab

    7、打印命令行有几个参数

    ~]# awk -F: 'BEGIN{print ARGC}' /etc/passwd /etc/fstab

    8、打印命令行第1个参数

    ~]# awk -F: 'BEGIN{print ARGV[1]}' /etc/passwd /etc/fstab

    9、自定义变量,打印hello world

    ~]# awk -v var='hello world!' 'BEGIN{print var}'

    10、格式化输出username,UID,shell类型

    ~]# awk -F: '{printf "Username:%-15s--Uid:%-4d--Shell:%s
    ",$1,$3,$NF}' /etc/passwd

    11、三目表达式来判断系统用户和普通用户

    ~]# awk -F: '{$3>=1000?usertype="Common":usertype="Sysuser"; printf "%20s:%s
    ",$1,usertype}' /etc/passwd

    12、查看fstab文件中的UUID

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

    13、查看passwd文件中UID大于1000的用户

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

    14、查看shell为bash的用户

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

    15、显示行首为从root到sshd的行

    ~]# awk '/^root/,/^sshd/{print $0}' /etc/passwd

    16、指定显示从第三行到第十行

    ~]# awk '(NR>=3&&NR<=10){print $0}' /etc/passwd

    17、打印表头和表尾,格式化输出

    ~]# awk -F: 'BEGIN{print "      username      uid  
    ------------------------"}{printf "%13s:%8d
    ",$1,$3}END{print "==========end========="}' /etc/passwd

    18、用if判断uid是否大于1000

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

    19、用双分支if语句输出用户的类型

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

    20、打印大于5个字段的行

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

    21、显示系统上磁盘的使用率超过20%的分区

    ~]# df |awk -F% '/^/dev/sd/{print $1}' |awk '{if($NF>20){print $1,$NF}}'

    22、统计grub.cfg文件中以linux16开头的行的所有字段长度

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

    23、统计grub.cfg文件中以linux16开头的行的所有字段长度的长度大于等于7的字段

    ~]# awk '/^[[:space:]]*linux16/{i=1; while(i<=NF){if(length($i)>=7) {print $i,length($i)}; i++}}' /boot/grub2/grub.cfg
    ~]# awk '/^[[:space:]]*linux16/{for(i=1;i<=NF;i++){if(length($i)>=7) {print $i,length($i)}}}' /boot/grub2/grub.cfg

    24、打印UID为偶数的用户

    ~]# awk -F: '{if($3%2) next; print $1,$3}' /etc/passwd

    25、统计tcp的连接状态

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

    26、统计httpd的日志,统计访问的ip

    ~# awk '{ip[$1]++}END{for(i in ip){printf "%20s:%d
    ",i,ip[i]}}' /var/log/httpd/access_log 

    27、统计tcp连接客户端IP地址

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

    个人学习笔记,记录于2018.5.15 19:14

  • 相关阅读:
    css div position to parent
    linux 解压缩/压缩命令大全
    button with backgroundimage programmaticaly
    使用数组初始化vector 对象
    AudioServicesPlaySystemSound
    objective-c 中随机数的用法 (3种:arc4random() 、random()、CCRANDOM_0_1() )
    指针和多维数组(例子需要好好消化理解)
    很经典的赋值算法之一:动态为数组有序赋值
    string 类的c_str 的成员函数
    自由存储区的空间 C++和C
  • 原文地址:https://www.cnblogs.com/L-dongf/p/9041946.html
Copyright © 2011-2022 走看看