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

    1.基本用法说明

    文本处理,输出格式化的文本报表,执行算数运算,执行字符串操作

    格式:

    awk [options] 'program' var=value file...

    awk [options] -f programfile var=value file...

    说明:

    program通常是被放在单引号中,并可以由三种部分组成

    ·BEGIN语句块   BEGIN{}:仅在开始处理文件中的文本之前执行一次

    ·模式匹配的通用语句块

    ·END语句块   END{}:仅在文本处理完成之后执行一次

    常见选项:

    -F“分隔符”指明输入时用到的字段分隔符,默认的分隔符是若干个连续空白符

    -v var=value 变量赋值

     第一步:执行BEGIN{action;...}语句块中的语句

    第二步:从文件或标准输入读取一行,然后执行pattern{action;...}语句块,他逐行扫描文件,从第一行到最后一行重复这个过程,直到文件全部被读取完毕。

    第三步:当读至输入流末尾时,执行END{action;...}语句块

    BEGIN语句块在awk开始从输入流中读取行之前被执行,这是一个可选的语句块,比如变量初始化,打印输出表格的表头等语句通常可以写在BEGIN语句块中

    END语句块在awk从输入流中读取完所有的行之后即被执行,比如打印所有行的分析结果这类信息汇总都是在END语句块中完成,它也是一个可选语句块

    pattern语句块中的通用命令是最重要的部分,也是可选的。如果没有提供pattern语句块,则默认执行{print},即打印每一个读取到的行,awk读取的每一行都会执行该语句块

     分隔符,域和记录

    由分隔符分隔的字段标记$1,$2....$n称为域标识,$0为所有域;注意和shell中的变量$符含义不同

    文件的每一行称为记录record

    如果省略action,则默认执行print$0的操作

    2.动作print

    格式

    print item1,item2,...

    说明

    逗号分隔符

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

    如省略item,相当于print$0

    固定字符需要用“”引起来,而变量和数字不需要

    范例

    [10:09:12 root@centos7 ~]$awk '{print "hello"}'
    [10:09:55 root@centos7 ~]$seq 3|awk '{print "hello"}' hello hello hello

      [10:11:35 root@centos7 ~]$seq 3|awk '{print 2*3}'
      6
      6
      6

    
    

    [10:18:37 root@centos7 ~]$awk -F: '{print "yang"}' hi
    wang
    wang
    wang
    wang
    wang

    该文件一共有几行,就打印几个yang

    [10:18:39 root@centos7 ~]$awk -F: '{print}' kao
    sdad:sdasd:sdjks:sdasd:sdsd
    sdsda:sdkaksd:sdkask
    ssadsd
    sdsd
    asdasdad

    打印全部内容

    [10:20:50 root@centos7 ~]$awk -F: '{print $0}' kao
    sdad:sdasd:sdjks:sdasd:sdsd
    sdsda:sdkaksd:sdkask
    ssadsd
    sdsd
    asdasdad

    加上$0也是打印全部的意思

    [10:22:45 root@centos7 ~]$awk -F: '{print $1,$3}' kao
    sdad sdjks
    sdsda sdkask
    ssadsd
    sdsd
    asdasdad

    以冒号为分隔符打印第一行和第三行

    [10:23:52 root@centos7 ~]$awk -F: '{print $1" "$3}' kao
    sdad sdjks
    sdsda sdkask
    ssadsd
    sdsd
    asdasdad

    中将用tab隔开

    [10:27:34 root@centos7 ~]$grep '^UUID' /etc/fstab |awk '{print $2,$3}'
    /boot xfs

    默认以空格做分隔符,不限制空格个数

    [10:44:22 root@centos7 ~]$df | awk -F"[ %]+" '{print $5}'
    Use
    0
    0
    2
    0
    4
    15
    1
    0

    以空隔百分号为分隔符取出分区利用率

    [10:50:28 root@centos7 ~]$df | awk -F' +|%' '/^/dev/sd/{print $1,$5}'
    /dev/sda1 15

    以空隔百分号为分隔符,以/dev/sd开头,取第一列和第五列

    [10:58:18 root@centos7 ~]$ifconfig eth0 |awk 'NR==2{print $2}'
    10.0.0.7

    以空格为分割符取第二行的第二列

    [11:15:16 root@centos7 ~]$ifconfig eth0 |awk '/netmask/{print $2}'
    10.0.0.7

    第二种方法

    [11:23:22 root@centos7 ~]$cat host 
    1 www.ybw.com
    2 blog.yang.com
    3 study.yang.com

    [11:24:23 root@centos7 ~]$awk -F"[ .]" '{print $2}' host 

    取出.ybw.com前面的主机名部分

    3.awk变量

    awk中的变量分为:内置和自定义变量

    常见内置变量

    范例

    FS:输入字段分隔符,默认为空白字符
    [11:33:37 root@centos7 ~]$awk -v FS=":" '{print $1,FS,$3}' /etc/passwd root : 0 bin : 1 daemon : 2 adm : 3 分隔符为:,引用FS

    [11:39:22 root@centos7 ~]$s=:;awk -F$s '{print $1$3}' /etc/passwd
    root0
    bin1

    设变量s=:,在awk里做为分隔符

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

    [11:39:30 root@centos7 ~]$awk -v FS=":" -v OFS="*" '{print $1,$3}' /etc/passwd
    root*0
    bin*1
    daemon*2

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

    NF:字段数量

    [11:48:28 root@centos7 ~]$awk -F: '{print NF}' /etc/passwd
    7
    7
    7

    显示这一行以冒号分割一共几个字段

    [11:51:53 root@centos7 ~]$awk -F: '{print $(NF-1)}' /etc/passwd
    /root
    /bin
    /sbin

    显示倒数第二个字段

    [14:17:02 root@aiyoubucuo ~]#cat nihao |awk -F"[ :]+" '{print $(NF-2)}'|tail -n +2|sort|uniq -c|sort -nr
    12 123.150.181.245
    1 114.246.101.61
    1 100.100.30.25

    取出连接数最多的三个ip

    NR:记录编号

    [14:19:08 root@aiyoubucuo ~]#cat nihao |awk -F"[ :]+" 'NR!=1{print $(NF-2)}'|sort|uniq -c|sort -nr
    12 123.150.181.245
    1 114.246.101.61
    1 100.100.30.25

    同上,NR!==1的意思是除去第一行都取,用来去表头

    [14:22:06 root@aiyoubucuo ~]#awk '{print NR,$0}' /etc/passwd
    1 root:x:0:0:root:/root:/bin/bash
    2 daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin

    显示行号

    FNR:各文件分别计数,记录的编号

    [14:27:56 root@centos7 ~]$awk '{print FNR,$0}' /etc/issue /etc/redhat-release
    1 S
    2 Kernel on an m
    3
    1 CentOS Linux release 7.9.2009 (Core)
    [14:28:57 root@centos7 ~]$awk '{print NR,$0}' /etc/issue /etc/redhat-release
    1 S
    2 Kernel on an m
    3
    4 CentOS Linux release 7.9.2009 (Core)

    FILENAME:当前文件名

    [14:37:06 root@centos7 ~]$awk '{print FNR,FILENAME,$0}' /etc/issue /etc/redhat-release
    1 /etc/issue S
    2 /etc/issue Kernel on an m
    3 /etc/issue
    1 /etc/redhat-release CentOS Linux release 7.9.2009 (Core)

    4.自定义变量

    自定义变量是区分字符大小写的,使用下面方式将进行赋值

    -v var=value

    [14:37:32 root@centos7 ~]$awk -v test1=test2="hello,gawk" 'BEGIN{print test1,test2}'
    test2=hello,gawk 

    5.操作符

    [14:54:26 root@centos7 ~]$awk 'BEGIN{i=0;print i++,i}'
    0 1
    [14:54:36 root@centos7 ~]$awk 'BEGIN{i=0;print ++i,i}'
    1 1
    n++用法

    [14:57:46 root@centos7 ~]$seq 3|awk 'n++'
    2
    3

    n=1时++=2,所以不显示第一行。用来排除行首

    [15:01:52 root@centos7 ~]$awk -F: '$3>=1000' /etc/passwd
    ybw:x:1000:1000:ybw:/home/ybw:/bin/bash
    yang:x:1001:1001::/home/yang:/bin/bash

    操作符比较
    [15:02:23 root@centos7 ~]$seq 10 |awk 'NR%2==0'
    2
    4
    6
    8
    10
    [15:03:34 root@centos7 ~]$seq 10 |awk 'NR%2==1'
    1
    3
    5
    7
    9

    取奇数,偶数行

    逻辑操作符

    与:&&,并且关系

    或:||,或者关系

    非:!,取反

    [15:15:24 root@centos7 ~]$awk -F: '$3>=0 && $3<=1000 {print $1,$3}' /etc/passwd

    第三列数字大于等于0,并且小于等于1000

    [15:21:48 root@centos7 ~]$awk -F: '$3>=0 || $3<=1000 {print $1,$3}' /etc/passwd

    从0到大于1000

    [15:21:48 root@centos7 ~]$awk -F: '($3==0) {print $1,$3}' /etc/passwd

    只取等于第三列等于0的行

    [15:25:50 root@centos7 ~]$awk -F: '!($3==0) {print $1,$3}' /etc/passwd

    取反

    5.条件判断if-else

    [15:49:39 root@centos7 ~]$df | awk -F' +|%' '/^/dev/sd/{if($5>=10)print $1,$5}'
    /dev/sda1 15
    判断以/dev/sd开头行的第5列是否大约10,如果大于则输出$1,$5

    6.循环for

    [16:13:31 root@centos7 ~]$awk 'BEGIN{sum=0;for(i=1;i<=100;i++){sum+=i};print sum}'
    5050

    7数组

    [16:54:36 root@centos7 ~]$ss -nta |awk 'NR!=1{state[$1]++}END{for (i in state){print i,state[i]}}'
    LISTEN 5
    ESTAB 1
    第一列不同的为i,state【i】为这种状态出现的次数
  • 相关阅读:
    遗传算法(Genetic Algorithm, GA)及MATLAB实现
    CCF CSP 201809-2 买菜
    PAT (Basic Level) Practice (中文)1008 数组元素循环右移问题 (20 分)
    PAT (Basic Level) Practice (中文)1006 换个格式输出整数 (15 分)
    PAT (Basic Level) Practice (中文)1004 成绩排名 (20 分)
    PAT (Basic Level) Practice (中文)1002 写出这个数 (20 分)
    PAT (Advanced Level) Practice 1001 A+B Format (20 分)
    BP神经网络(原理及MATLAB实现)
    问题 1676: 算法2-8~2-11:链表的基本操作
    问题 1744: 畅通工程 (并查集)
  • 原文地址:https://www.cnblogs.com/aiyoubucuo/p/14243115.html
Copyright © 2011-2022 走看看