• gawk进阶


    一、使用变量

     gawk支持两种不同类型的变量:

    • 内建变量
    • 自定义变量

    1.1 内建变量

    ①字段和记录分隔符变量

     FIELDWIDTHS:有空格分割的一列数字,定义了每个数据字段确切宽度

    • FS:输入字段分隔符
    • RS:输入记录分隔符
    • OFS:输出字段分隔符
    • ORS:输出记录分隔符
    chen@ubuntu:~/shell/ch22$ gawk 'BEGIN{FS=","; OFS="-"} {print $1,$2,$3}' data1
    data11-data12-data13
    data21-data22-data23
    data31-data32-data33
    chen@ubuntu:~/shell/ch22$ cat data1 
    data11,data12,data13,data14,data15
    data21,data22,data23,data24,data25
    data31,data32,data33,data34,data35
    chen@ubuntu:~/shell/ch22$ gawk 'BEGIN{FS=","; OFS="--"} {print $1,$2,$3}' data1
    data11--data12--data13
    data21--data22--data23
    data31--data32--data33
    chen@ubuntu:~/shell/ch22$ gawk 'BEGIN{FS=","; OFS="<-->"} {print $1,$2,$3}' data1
    data11<-->data12<-->data13
    data21<-->data22<-->data23
    data31<-->data32<-->data33
    
    cat data1b 
    1005.3247596.37
    115-2.349194.00
    05180.1298100.1
    chen@ubuntu:~/shell/ch22$ gawk 'BEGIN{FIELDWIDTHS="3 5 2 5"}{print $1,$2,$3,$4}' data1b
    100 5.324 75 96.37
    115 -2.34 91 94.00
    051 80.12 98 100.1
    
    
    chen@ubuntu:~/shell/ch22$ cat data2
    Riley Mullen
    123 Main Street
    Chicago, IL 60601
    (312)555-1234
    
    Frank Williams
    456 Oak Street
    Indianapolis, IN 46201
    (317)555-9876
    
    Haley Snell
    4231 Elm Street
    Detroit, MI 48201
    (313)555-4938
    chen@ubuntu:~/shell/ch22$ gawk 'BEGIN{FS="
    "; RS=""}{print $1,$4}' data2
    Riley Mullen (312)555-1234
    Frank Williams (317)555-9876
    Haley Snell (313)555-4938
    #把换行符变成字段分隔符,把空行当做一个字段分隔符
    字段分隔符例子

    ②数据变量

    • ARGC:当前命令行参数个数
    • ARGIND:当前文件在ARGV中的位置
    • ARGV:包含命令行参数的数组
    • CONVFMT:数字的转换格式
    • ENVIRON:当前shell环境变量及其值组成的关联数组
    • ERRNO:当读取或闭输入文件发生错误时的系统错误号
    • FILENAME:用作gawk输入数据的数据文件的文件名
    • FNR:当前数据文件中的数据行数
    • IGNORECASE:设成非零值时,忽略gawk命令中出现的字符串的字符大小写
    • NF:数据文件中的字段总数
    • NR:已处理的输入记录数
    • OFMT:数字的输出格式,默认值为%.6g
    • RLENGTH:由match函数所匹配的子字符串的长度
    • RSTART:由match函数所匹配的子字符串的起始位置
    chen@ubuntu:~/shell/ch22$ gawk 'BEGIN{print ARGC,ARGV[1]}' data1
    2 data1
    chen@ubuntu:~/shell/ch22$ cat data1
    data11,data12,data13,data14,data15
    data21,data22,data23,data24,data25
    data31,data32,data33,data34,data35
    chen@ubuntu:~/shell/ch22$ gawk 'BEGIN{print ARGC,ARGV[0]}' data1
    2 gawk
    chen@ubuntu:~/shell/ch22$ gawk '
    > BEGIN{
    > print ENVIRON["HOME"]
    > print ENVIRON["PATH"]
    > }'
    /home/chen
    /home/chen/bin:/home/chen/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
    chen@ubuntu:~/shell/ch22$ gawk 'BEGIN{FS=":"; OFS=":"} {print $1,$NF}' /etc/passwd
    root:/bin/bash
    daemon:/usr/sbin/nologin
    bin:/usr/sbin/nologin
    sys:/usr/sbin/nologin
    
    chen@ubuntu:~/shell/ch22$ gawk 'BEGIN{FS=","}{print $1,"FNR="FNR}' data1 data1
    data11 FNR=1
    data21 FNR=2
    data31 FNR=3
    data11 FNR=1
    data21 FNR=2
    data31 FNR=3
    chen@ubuntu:~/shell/ch22$ cat data1
    data11,data12,data13,data14,data15
    data21,data22,data23,data24,data25
    data31,data32,data33,data34,data35
    数据变量例子

    1.2 自定义变量

    gawk自定义变量名可以是任意数目的字母、数字和下划线。gawk变量名区分大小写。

    ①在脚本中给变量赋值

    chen@ubuntu:~/shell/ch22$ gawk '
    > BEGIN{
    > testing="This is a test"
    > print testing
    > }'
    This is a test
    chen@ubuntu:~/shell/ch22$ gawk '
    > BEGIN{
    > testing="This is a test"
    > print testing
    > testing=45
    > print testing
    > }'
    This is a test
    45
    
    chen@ubuntu:~/shell/ch22$ gawk 'BEGIN{x=4; x= x * 2 + 3; print x}'
    11
    变量赋值例子

    ②在命令行上给变量赋值

    chen@ubuntu:~/shell/ch22$ cat script1 
    BEGIN{FS=","}
    {print $n}
    chen@ubuntu:~/shell/ch22$ gawk -f script1 n=2 data1
    data12
    data22
    data32
    chen@ubuntu:~/shell/ch22$ gawk -f script1 n=3 data1
    data13
    data23
    data33
    
    chen@ubuntu:~/shell/ch22$ gawk -f script2 n=3 data1
    The starting value is 
    data13
    data23
    data33
    chen@ubuntu:~/shell/ch22$ cat script2 
    BEGIN{print "The starting value is",n; FS=","}
    {print $n}
    
    chen@ubuntu:~/shell/ch22$ gawk -v n=3 -f script2 data1
    The starting value is 3
    data13
    data23
    data33
    命令行上给变量赋值例子

    二、处理数组

    2.1 定义数组变量

    数组变量赋值的格式如下:

    var[index] = element

    其中var是变量,index是关联数组的索引值,element是数据元素

    chen@ubuntu:~/shell/ch22$ gawk 'BEGIN{
    > capital["Illinois"] = "Springfield"
    > print capital["Illinois"]
    > }'
    Springfield
    chen@ubuntu:~/shell/ch22$ gawk 'BEGIN{
    > var[1] = 34
    > var[2] = 3
    > total = var[1] + var[2]
    > print total
    > }'
    37
    定义数组变量

    2.2 遍历数组变量

    gawk中遍历数组,用一种for的特殊形式

    for ( var in array )
    {
      statements
    }

    使用例子:

    chen@ubuntu:~/shell/ch22$ gawk 'BEGIN{
    var["a"] = 1
    var["g"] = 2
    var["m"] = 3
    var["u"] = 4
    for ( test in var)
    {
        print "Index:",test," - Value:",var[test]
    }
    }'
    Index: u  - Value: 4
    Index: m  - Value: 3
    Index: a  - Value: 1
    Index: g  - Value: 2
    数组遍历

    2.3 删除数组变量

    从关联数组中删除数组索引要用一个特殊的命令。

    delete array[index]

    删除命令会从数组中删除关联索引值和相关的数据元素值

    chen@ubuntu:~/shell/ch22$ gawk 'BEGIN{
    > var["a"] = 1
    > var["g"] = 2
    > for (test in var)
    > {
    >     print "Index:",test," - Value:",var[test]
    > }
    > delete var["g"]
    > print "---"
    > for (test in var)
    >     print "Index:",test," - Value:",var[test]
    > }'
    Index: a  - Value: 1
    Index: g  - Value: 2
    ---
    Index: a  - Value: 1
    删除例子

    三、使用模式

    本节将会演示如何在gawk脚本中用匹配模式来限定程序脚本作用在哪些记录上。

    3.1 正则表达式

    在使用正则表达式时,正则表达式必须出现在它要控制的程序脚本的左花括号前。 

    myfly2@ubuntu:~$ cat data1
    data11,data12,data13,data14,data15
    data21,data22,data23,data24,data25
    data31,data32,data33,data34,data35
    myfly2@ubuntu:~$ awk 'BEGIN{FS=","} /11/{print $1}' data1
    data11
    myfly2@ubuntu:~$ awk 'BEGIN{FS=","} /,d/{print $1}' data1
    data11
    data21
    data31
    匹配符例子

    3.2 匹配操作符

    匹配操作符:允许将正则表达式限定在记录中的特定数据字段。

    匹配操作符是波浪线(~)。可以指定匹配操作符、数据字段变量以及要匹配的正则表达式。

    $1 ~ /^data/

    $1:代表记录中的第一个数据字段。这个表达式会过滤出第一个字段以文本data开头的所有记录。

    myfly2@ubuntu:~$ awk 'BEGIN{FS=","} $2 ~ /^data2/{print $0}' data1
    data21,data22,data23,data24,data25
    
    myfly2@ubuntu:~$ awk -F: '$1 ~ /myfly/{print $1,$NF}' /etc/passwd
    myfly2 /bin/bash
    匹配操作符例子

    $1 !~ /expression/

    myfly2@ubuntu:~$ awk -F: '$1 !~ /myfly2/{print $1,$NF}' /etc/passwd
    root /bin/bash
    daemon /usr/sbin/nologin
    bin /usr/sbin/nologin
    sys /usr/sbin/nologin
    sync /bin/sync
    games /usr/sbin/nologin
    man /usr/sbin/nologin
    lp /usr/sbin/nologin
    !~例子

    3.3 数学表达式

    除了正则表达式,也可以在匹配模式中用数学表达式。 常用的表达式:

    • x == y:值x等于y
    • x <= y:值x小于等于y
    • x < y:值x小于y
    • x >= y:值x大于等于y
    • x > y:值x大于y
    myfly2@ubuntu:~$ awk -F: '$4 == 0{print $1}' /etc/passwd
    root
    myfly2@ubuntu:~$ awk -F, '$1 == "data"{print $1}' data1
    myfly2@ubuntu:~$ cat data1
    data11,data12,data13,data14,data15
    data21,data22,data23,data24,data25
    data31,data32,data33,data34,data35
    myfly2@ubuntu:~$ awk -F, '$1 == "data11"{print $1}' data1
    data11
    
    #与正则表达式不同,数学表达式必须完全匹配
    例子

    四、结构化命令

    4.1 if语句

    gawk支持标准的if-then-else格式的if语句。 

    格式: if (condition)

      statement1

    也可以这样:if (condition) statement1

    awk '{if ($1 > 20) print $1}' data4
    50
    34
    myfly2@ubuntu:~/shell/ch22$ awk '{
    > if ($1 > 20)
    > {
    >     x = $1 * 2
    >     print x
    > }
    > }' data4
    100
    68
    if-then例子

    4.2 while语句

    基本循环的格式:

    while (condition)

    {

      statement1

    }

    myfly2@ubuntu:~/shell/ch22$ awk '{
    total = 0
    i = 1
    while (i<4)
    {
        total += $i
        i++
    }
    avg = total / 3
    print "Average:",avg
    }' data5
    Average: 128.333
    Average: 137.667
    Average: 176.667
    myfly2@ubuntu:~/shell/ch22$ awk '{
    > total = 0
    > i = 1
    > while (i<4)
    > {
    >     total += $i
    >     if(i == 2)
    >         break
    >     i++
    > }
    > avg = total /2
    > print "The average of the first two data elements is:",avg
    > }' data5
    The average of the first two data elements is: 125
    The average of the first two data elements is: 136.5
    The average of the first two data elements is: 157.5
    while例子

    4.3 do-while语句

    格式:

    do

    {

      statements

    }

    myfly2@ubuntu:~/shell/ch22$ awk '{
    > total = 0
    > i = 1
    > do
    > {
    >     total += $i
    >     i++
    > }
    > while (total < 150)
    > print total }' data5
    250
    160
    315
    do while例子

    4.4 for语句

    格式:for( variable assignment; condition; iteration process)

    myfly2@ubuntu:~/shell/ch22$ awk '{
    > total = 0
    > for(i=1;i<4;i++)
    > {
    >     total += $i
    > }
    > avg = total / 3
    > print "Average:",avg
    > }' data5
    Average: 128.333
    Average: 137.667
    Average: 176.667
    for例子

    五、格式化打印

    六、内建函数

    6.1 数学函数

    6.2 字符串函数

    6.3 时间函数

    七、自定义函数

    7.1 定义函数

    7.2 使用自定义函数

    7.3 创建函数库

    八、实例

  • 相关阅读:
    elementui form-item中多个字段校验
    Element-ui的 el-form 使用 v-if校验失灵问题
    fullcalendar title换行
    html拼接
    element-ui cascader 省市区 动态加载
    切换vue项目初始化路径
    用JavaScript获取当月第一天和最后一天
    小宝和小黑
    python目录
    3
  • 原文地址:https://www.cnblogs.com/ch122633/p/10346995.html
Copyright © 2020-2023  润新知