zoukankan      html  css  js  c++  java
  • awk数组详解、实战

    1.其它编程语言数组的下标一般从0开始,awk中数组下标默认从1开始,也可以从0开始设置:

    awk 'BEGIN{huluwa[0]="大娃";huluwa[1]="二娃";huluwa[3]="三娃";print huluwa[1]}'
    二娃
    awk 'BEGIN{huluwa[0]="大娃";huluwa[1]="二娃";huluwa[3]="三娃";huluwa[4]="";print huluwa[4]}'
    第二条命令没有内容输出
    

    2.在awk中,元素的值设置为"空字符串"是合法的,所以不能用元素值是否为空,判断该元素是否存在于数组中.

    当一个元素不存在于数组时,引用该元素,awk会自动创建这个元素,为这个元素赋值为空字符串,
    所以引用一个不存在于数组的元素时,这个元素已经被赋值了,也就是已经存在了.
    awk 'BEGIN{huluwa[0]="大娃";huluwa[1]="二娃";huluwa[3]="三娃";huluwa[4]="";
    if(5 in huluwa){print "第6个元素存在就能看到这句话"}}'
    

    3.使用语法if(下标 in 数组名),可以判断数组中是否存在对应的元素.

    awk 'BEGIN{huluwa[0]="大娃";huluwa[1]="二娃";huluwa[3]="三娃";huluwa[4]="";
    if(!(5 in huluwa)){print "第6个元素存在就能看到这句话"}}'
    第6个元素存在就能看到这句话
    

    4.用delete可以删除数组中的元素,也可以删除整个数组

    awk 'BEGIN{huluwa["yiwa"]="大娃";huluwa["erwa"]="二娃";
    huluwa["sanwa"]="三娃";print huluwa["yiwa"];delete huluwa["yiwa"];print huluwa["yiwa"]}'
    大娃
    
    awk 'BEGIN{huluwa["yiwa"]="大娃";huluwa["erwa"]="二娃";
    huluwa["sanwa"]="三娃";print huluwa["yiwa"];delete huluwa;print huluwa["yiwa"]}'
    大娃
    

    5.两种for循环

    awk 'BEGIN{huluwa[1]="大娃";huluwa[2]="二娃";huluwa[3]="三娃";
    huluwa[4]="四 娃";for(i=1;i<=4;i++){print i,huluwa[i]}}'
    1 大娃
    2 二娃
    3 三娃
    4 四娃
    awk 'BEGIN{ huluwa["yiwa"]="大娃";huluwa["erwa"]="二娃";huluwa["sanwa"]="三 娃"huluwa["siwa"]="四娃";for(i in huluwa){print i,huluwa[i]} }'
    siwa 四娃
    yiwa 大娃
    erwa 二娃
    sanwa 三娃
    

    发现数组其实是无序的,可以把它当成python中的字典.

    6.数组应用1:

    awk 'BEGIN{ a=1; print a; a++; print a}'
    1
    2
    当字符串或者空字符串参与运算时,将被当做数字0.
    awk 'BEGIN{ a="test"; print a; a++; print a; a++; print a}'
    test
    1
    2
    awk 'BEGIN{ a=""; print a; a++; print a; a++; print a}'
    
    1
    2
    引用数组中一个不存在的元素时,元素被赋值为空字符串,参与运算时被当做0使用
    awk 'BEGIN{ print a["ip"]; a["ip"]++;a["ip"]++; print a["ip"]}'
    
    2
    

    统计ip出现的次数:

    # cat test10
    192.168.1.1
    192.168.1.2
    192.168.1.3
    192.168.1.12
    192.168.1.3
    192.168.1.3
    192.168.1.2
    192.168.1.4
    192.168.1.12
    192.168.1.1
    # awk '{count[$1]++} END{for(i in count) {print i,count[i]} }' test10
    192.168.1.12 2
    192.168.1.1 2
    192.168.1.2 2
    192.168.1.3 3
    192.168.1.4 1
    awk实现统计ip次数

    7.数组应用2:

    # cat test4
    zhangsan lisi
    wangwu zhaoliu
    zhouqi zhangsan wangwu
    lisi zhaoliu
    # awk '{ for(i=1;i<=NF;i++){a[$i]++} } END{ for(j in a){print j,a[j]} }' test4
    zhaoliu 2
    zhangsan 2
    wangwu 2
    lisi 2
    zhouqi 1
    awk统计名字出现次数

    8.数组应用3:

    # cat a.txt
    李四|000002
    张三|000001
    王五|000003
    赵六|000004
    # cat b.txt
    000001|10
    000001|20
    000002|30
    000002|15
    000002|45
    000003|40
    000003|25
    000004|60
    # awk -F '|' 'NR == FNR{a[$2]=$1;} NR>FNR {print a[$1],"|", $0}' a.txt b.txt
    # awk -F "|" 'NR == FNR{a[$2]=$1;next}{print a[$1],"|",$0}' a.txt b.txt
    # awk -F "|" 'NR == FNR{a[$2]=$0;next}{print a[$1]"|"$2}' a.txt b.txt
    张三 | 000001|10
    张三 | 000001|20
    李四 | 000002|30
    李四 | 000002|15
    李四 | 000002|45
    王五 | 000003|40
    王五 | 000003|25
    赵六 | 000004|60
    数组的活学活用

    解释说明:

    在NR == FNR时,也就是在处理前四行时,将数组的格式变成:

    a={"000002":"李四","000001":"张三","000003":"王五","000001":"赵六"},

    处理剩下的行时,用a[$1]去找姓名,再加上每一行内容就是想要的内容.

    9.内置函数(用到时再研究)

    常用的算数函数--rand、srand、int;
    字符串函数--sub、gsub替换某些文本,length函数获取指定字符串长度;
    index函数获取的到指定字符串在整个字符串中的位置;
    split函数可以将指定的字符串按照指定的分隔符分割,将每段内容赋值到数组中,从而动态的创建数组.
    

    10.三元运算

    三元运算语法:条件?结果1:结果2

    使用变量usertype接收了三元运算后的返回值,当条件成立时,usertype被赋值为"系统用户",反之为"普通用户"
    awk -F: '{ usertype=$3<500?"系统用户" : "普通用户"; print $1,usertype}' /etc/passwd
    表达式1?表达式2:表达式3
    awk -F: '{$3<500?a++:b++}END{print a,b}' /etc/passwd
    

    11.打印奇偶行

    # cat test11
    第 1 行
    第 2 行
    第 3 行
    第 4 行
    第 5 行
    第 6 行
    第 7 行
    第 8 行
    第 9
    test11文件内容

    a.当使用了模式时,如果省略了对应的动作,会默认输出整行.

    awk '$2>7' test11
    第 8 行
    第 9 行
    

    b.awk中,0或空字符串表示'假',非0值或非空字符串表示'真'.

    # awk '1{print $0}' test3
    hello
    helllo
    # awk '1' test3
    hello
    helllo
    # awk '0' test3  什么也不会输出
    # awk '!0' test3  0取反,即为真
    hello
    helllo
    # awk 'i=1' test3
    hello
    helllo
    

    c.awk开始处理第一行,i被初始化,值为空,模式为假,所以i=!i,是将取反后的值又赋给了i,

    此刻i的值为真,在awk处理第一行文本时i为真,且省略了动作,就会打印第一行内容;

    在处理第二行时,将在第一行时为真的i取反,此时i为假,故第二行没有被打印.

    awk 'i=!i' test11
    第 1 行
    第 3 行
    第 5 行
    第 7 行
    第 9 行
    awk '!(i=!i)' test11 或 awk 'a=!(i=!i)' test11
    第 2 行
    第 4 行
    第 6 行
    第 8 行
    

    12.awk数组统计状态

    # 先解释split和数组时怎样结合的:
    awk -v ts="dawa;erwa;sanwa" 'BEGIN{ split(ts,huluwa,";");for(i in huluwa){print i,huluwa[i]} }'
    1 dawa
    2 erwa
    3 sanwa
    # split按照指定的分隔符切割字符串,将切割后的字段赋值到元组中,键是数字,值是对应字段.
    netstat -pnta 2>&1|grep 'ESTABLISHED'|head | awk '{ split($5,a,":");b=a[1];c=a[2];{print b,c} }'
    127.0.0.1 6025
    127.0.0.1 6026
    127.0.0.1 6025
    127.0.0.1 6023
    127.0.0.1 6025
    127.0.0.1 6023
    127.0.0.1 6023
    127.0.0.1 6026
    127.0.0.1 9090
    127.0.0.1 6025
    # 统计ESTABLISHED(已建立的连接)的远程ip:
    netstat -pnta 2>&1|grep 'ESTABLISHED'|awk '{split($5,a,":");b=a[1];count[b]++}END{for(i in count)print i,count[i]}
    

    13.注意几点书写:

    不同模式之间用{}隔开;

    数字的运算、判断放在()中;

    数组的运算放在{}中;

    print放在{}中.

    参考博客:https://www.cnblogs.com/xudong-bupt/p/3721210.html

    参考博客:https://www.cnblogs.com/jiqianqian/p/7944013.html

    朱双印的博客写的很详细,通俗易懂:http://www.zsythink.net/archives/2093

  • 相关阅读:
    vmware和主机通信方法
    曾经的读书计划
    Linux下的autoconf和automake
    Nor Flash读写方法
    Linux下的动态库和静态库
    asp.net读取Xml文件到DataSet,以及DataSet保存为Xml,利用自带的强大功能
    SqlServer 2000/2005 列转行 行转列收集
    GridView 模板列 在后台获取该行某控件的值 例如批量修改
    C# DllImport的用法 调用Window的一些常用功能
    C#通用数据库操作类 支持Access/MSSql/Orale/MySql等数据库
  • 原文地址:https://www.cnblogs.com/fawaikuangtu123/p/10008645.html
Copyright © 2011-2022 走看看