• Shell 工具之 gawk


    gawk 程序是 Unix 中原 awk 程序的 GNU 版本。awk 程序在流编辑方面比 sed 编辑器更先进的是:它提供了一种编程语言而不仅仅是编辑器命令行。

    gawk 格式

    gawk options program file

    表:gawk 选项

    选项  描述
    -F fs 指定描绘一行中数据字段的文件分隔符
    -f file 指定读取程序的文件名
    -v var=value 定义 gawk 程序中使用的变量和默认值
    -mf N 指定数据文件中要处理的字段的最大数目
    -mr N 指定数据文件中中的最大记录大小
    -W keyword 指定 gawk 的兼容模式或警告级别

    1. 自命令行读取程序脚本

    gawk 程序脚本由左大括号和右大括号定义。脚本命令必须放置在两个大括号之间。由于gawk命令行假定脚本是单个文本字符串,所以必须将脚本放到单引号内。

    # gawk '{print "hello world"}'    
    hello
    hello world
    hi
    hello world

    2. 使用数据字段变量
    gawk 将下面的变量分配给文本行中检测到的每个数据字段:
    $0代表整个文本行
    $1代表文本行中的第1个数据字段,$2等依次类推
    gawk 的默认分隔符为空白字符。

    # gawk '{print $1}' data1
    this

    使用-F来指定字段分隔符
    # gawk -F: '{print $1}' /etc/passwd                                   
    root
    bin
    daemon
    adm

    3. 在程序脚本中使用多个命令

    要在命令行指定的程序脚本中使用多个命令,只需在各命令之间加一个分号:

    # echo "this is a test" | gawk '{$4="gawk";print $0}'   
    this is a gawk

    也可以使用次提示符每次输入一行程序脚本命令:

    $ gawk '{

    > $4="testing"

    > print $0 }' 

    This is not a good test.

    This is not testing good test.


    4.从文件读取程序

    gawk 编辑器允许您将程序保存在文件中并在命令行引用他们:

    # cat gawktest 
    {
    text="'s home directory is "
    print $1 text $6                                                 //gawk程序中使用变量无需加美元符
    }
    # gawk -F: -f gawktest passwd 
    root's home directory is /root
    bin's home directory is /bin
    daemon's home directory is /sbin
    adm's home directory is /var/adm

    5. 在处理数据之前/之后允许脚本

    BEGIN 关键字允许指定在读取数据之前 gawk 执行的程序脚本

    END 关键字允许指定在读取数据之后 gawk 执行的程序脚本

    # cat beginend 
    BEGIN {                                            //BEGIN处理数据前运行的脚本
    print "userid   shell"
    print "------   -----"
    FS=":"                                             //FS脚本中定义分隔符
    }

    {
    print $1 "      " $7                               //引号内为制表符,这样输出的结果才能对齐
    }

    END {                                              //END处理数据后运行的脚本
    print "end of list"
    }
    # gawk -f beginend passwd 
    userid  shell
    ------  -----
    root    /bin/bash
    bin     /sbin/nologin
    daemon  /sbin/nologin
    adm     /sbin/nologi
    ...
    end of list

    使用变量

    gawk 编程语言支持两种不同类型的变量:

    内置变量

    用户定义的变量

    内置变量

    gawk 程序使用内置变量引用程序数据内的特定功能。

    数据字段变量允许使用美元符号和数据字段在记录中的数字位置引用数据记录中的单个数据字段。如$1。可以使用FS内置变量更改字段分隔符号。

    FS内置变量属于一组内置变量,用于控制 gawk 在输入数据和输出数据中处理字段和记录的方式。

    gawk数据字段和记录变量

    变量

    描述

    FIELDWIDTHS

    以空格分隔的数字列表,用空格定义每个数据字段的精确宽度

    FS

    输入字段分隔符号

    RS

    输入记录分隔符号

    OFS

    输出字段分隔符号

    ORS

    输出记录分隔符号

    默认情况下,gawk将OFS变量设置为空格:

    [root@wh tmp]# cat data1

    data11,data12,data13,data14,data15

    data21,data22,data23,data24,data25

    data31,data32,data33,data34,data35

    [root@wh tmp]# gawk 'BEGIN{FS=","} {print $1,$2,$3}' data1

    data11 data12 data13

    data21 data22 data23

    data31 data32 data33

     

    通过设置OFS变量,可以使用任何字符串分隔符输出中的数据字段:

    [root@wh tmp]# gawk 'BEGIN{FS=",";OFS="-"} {print $1,$2,$3}' data1

    data11-data12-data13

    data21-data22-data23

    data31-data32-data33

    [root@wh tmp]# gawk 'BEGIN{FS=",";OFS="--"} {print $1,$2,$3}' data1

    data11--data12--data13

    data21--data22--data23

    data31--data32--data33

    [root@wh tmp]# gawk 'BEGIN{FS=",";OFS="<-->"} {print $1,$2,$3}' data1

    data11<-->data12<-->data13

    data21<-->data22<-->data23

    data31<-->data32<-->data33

     

    更多gawk内置变量

    变量

    描述

    ARGC

    出现的命令行参数的个数

    ARGIND

    当前正在处理的文件在ARGV中的索引

    ARGV

    命令行参数数组

    CONVFMT

    数字的转换格式(参见printf语句)。默认值为%.6g

    ENVIRON

    当前shell环境变量及其值的关联数组

    ERRNO

    当读取或关闭输入文件时发生错误时的系统错误

    FILENAME

    用于输入到gawk程序的数据文件的文件名

    FNR

    数据文件的当前记录号

    IGNORECASE

    如果设置为非0,则忽略gawk命令中使用的字符串的大小写

    NF

    数据文件中数据字段的个数

    NR

    已处理的输入记录的个数

    OFMT

    显示数字的输出格式。默认为%,6g

    RLENGTH

    匹配函数中匹配上的子字符串的长度

    RSTART

    匹配函数中匹配上的子字符串的开始索引

     

    [root@wh tmp]# gawk 'BEGIN {print ARGC,ARGV[1]}' data1

    2 data1

    ARGC变量表示命令行上有两个参数。这包括gawk命令和data1参数(注意,程序脚本不是参数)。ARGV数组以索引0开始,它表示命令。第一个数组值是gawk命令后的第一个命令行参数。与shell变量不同的是在脚本中引用gawk变量时,不需要再变量名称前加美元符号。

     

    FNR、NF和NR变量在gawk程序中用于跟踪数据字段和记录。有时,你可能不知道记录中具体有多少个数据字段。NF变量允许指出记录中的最后一个数据字段而不需要知道它的位置:

    [root@wh tmp]# gawk 'BEGIN{FS=":"; OFS=":"} {print $1,$NF}' /etc/passwd

    root:/bin/bash

    bin:/sbin/nologin

    daemon:/sbin/nologin

    adm:/sbin/nologin

    lp:/sbin/nologin

    sync:/bin/sync

     

    NF变量包含数据文件中最后一个数据字段的数值。通过在前面加美元符号,可以将其作为数据字段变量使用。

     

    FNR和NR变量相类似,只是略有不同。FNR变量包含当前数据文件中处理的记录数。NR变量包含已经处理的记录的总数。让我们看几个例子来了解它们的不同之处:

    [root@wh tmp]# 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

     

    本例中,gawk程序命令行定义了两个输入文件(它两次都指定了同一输入文件)。脚本打印第一个数据字段的值和FNR变量的当前值。请注意,FNR变量在gawk程序处理第二个数据文件时被重新设置为1。

    现在,让我们添加NR变量,看看结果是什么:

    [root@wh tmp]# gawk 'BEGIN{FS=",";} {print $1,"FNR="FNR,"NR="NR} END {print "There were",NR,"records processed"}' data1 data1

    data11 FNR=1 NR=1

    data21 FNR=2 NR=2

    data31 FNR=3 NR=3

    data11 FNR=1 NR=4

    data21 FNR=2 NR=5

    data31 FNR=3 NR=6

    There were 6 records processed

     

    FNR变量值在gawk处理第二个数据文件时被重置,但NR变量在处理第二个数据文件时仍然继续增加。也就是说,如果只使用一个 文件作为输入,则FNR和NR值将是相同的。如果使用多个数据文件作为输入,则FNR值在每次处理新的数据文件时重置,而NR值对所有数据文件进行累计计数。

    使用数组

    定义数组变量

    格式:

    var[index] = element

    var 是变量的名称, index 是关联数组的索引值, element 是数组元素值

    capital["Illinois"] = "Springfield"

    在引用数组变量时,必须包括索引值才能检索相应的数据元素值。

    $ gawk 'BEGIN{

    > capital["Illinois"] = "Springfield"

    > print capital["Illinois"]

    > }'

    Springfield

    在数组变量中递归

    可以使用特殊格式的 for 语句

    for {var in array}

    {

      statements

    }

    示例

    $ 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

    注意:索引值不是以一定的顺序返回的。

    删除数组变量

    格式:

    delete array[index]

    delete 命令从数组删除关联索引值和关联的数组元素值。

    使用模式

    正则表达式

    $ gawk 'BEGIN{FS=","} /11/{print $1}' data1

    匹配操作符(~)

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

    格式:

    $1 ~ /^data/

    用于在数据文件中搜索特定的数据元素

    $ gawk -F: '$1 ~ /rich/{print $1, $NF}' /etc/passwd

    rich /bin/bash

    此示例在第一个数据字段中搜索文本 rich,当找到模式时,打印出记录的第一个和最后一个数据字段。

    数学表达式

    常用的数学比较表达式

    ◆  x == y  值 x 等于 y

    ◆  x <= y 值 x 小于等于 y

    ◆  x < y 值 x 小于 y

    ◆  x > y 值 x 大于 y

    ◆  x >= y 值 x 大于等于 y

    $ gawk -F, '$1 == "data"{print $1}' data1

    结构化命令

    if 语句

    格式:
      if (condition)

      statement1

    或者

      if (condition)  statement1

    示例

    [root@tang sh19]# gawk '{
    > if($1 > 20)
    > {
    > x = $1 * 2
    > print x
    > }
    > }' data4
    100
    68

    if-else 语句

    格式

      if (condition)

      statement1

      else

      statement2

    或者

      if (condition) statement1; else statement2

    示例

    [root@tang sh19]# gawk '{
    > if($1 >20)
    > {
    > x = $1 * 2
    > print x
    > } else
    > {
    > x = $1 / 2
    > print x
    > }
    > }' data4
    5
    2.5
    6.5
    100
    68

    while 语句

    while 语句为 gawk 程序提供了基本的循环功能。

    格式

    while (condition)

    {

      statements

    }

    示例

    [root@tang sh19]# gawk '{
    > total = 0
    > i = 1
    > while (i < 4)
    > {
    > total += $i
    > i++
    > }
    > avg = total / 3
    > print "Average:", avg
    > }' data5
    Average: 176.667
    Average: 137.667
    Average: 128.333

    另外,gawk 支持在while循环中使用 break 和 continue 语句。

    do-while 语句

    格式

    do

    {

      statements

    } while (condition)

    示例

    [root@tang sh19]# gawk '{
    > total = 0
    > i = 1
    > do
    > {
    > total += $i
    > i++
    > } while (total < 150)
    > print total
    > }' data5
    315
    160
    250

    for 语句

    gawk 支持C 语言形式的 for 循环

    格式

    for( variable assignment; condition; iteration process)

    示例

    [root@tang sh19]# gawk '{
    > total = 0
    > for (i=1; i<4; i++)
    > {
    > total += $i
    > }
    > avg = total / 3
    > print "Average:", avg
    > }' data5
    Average: 176.667
    Average: 137.667
    Average: 128.333

    格式化打印

    printf 命令的格式

    printf "format string", var1, var2 ...

    formate string是格式化输出的关键。它使用文本元素和格式化说明符说明了格式化后输出的显示方式。

    格式化说明符格式:

    %[modifier]control-letter

    control-letter 表示要显示的数据值类型的字符代码

    modifer 定义可选的格式化功能

    格式化说明符控制字

    控制字 描述 控制字 描述
    c 将数据显示为ASCII字符 g 以科学计数法和浮点数的较短者显示数字
    d 显示整数值 o 显示八进制数值
    i 显示整数值(与d相同) s 显示文本字符串
    e 用科学计数法显示数字 x 显示十六进制数值
    f 显示浮点数值 X 显示十六进制数值,但对A到F使用大写字母

    除了控制字以外,还可以使用3中修饰符更多地控制输出。

    width:指定输出字段最新宽度的数字值。

    prec:指定浮点数中十进制数小数点右侧位数的数值,或者文本字符串中显示的最大字符数。

    -(减号) :表示在将数据放到格式化空间时不使用右对齐,而是使用左对齐。

    示例

    $ gawk '{

    > total = 0

    > for (i=1; i<4; i++)

    > {

    >      total += $i;

    > }

    > avg = total / 3;

    > printf "Average: $%5.1f ", avg

    > }' data5

    内置函数

    数学函数

    字符串函数

    时间函数

    除了标准的数学函数,gawk 还提供了一些函数用于数据的位操作处理

    and(v1, v2) 执行 v1 和 v2 的于操作

    compl(val) 执行对 val 的补位

    lshift(val, count) 将值 val 向左移动 count 位

    or(v1, v2) 执行 v1 和 v2 的或操作

    rshift(val, count) 将值 val 向右移动 count 位

    xor(v1, v2) 执行 v1 和 v2 的异或操作

  • 相关阅读:
    WSL2
    坐标系变换
    Python websocket
    PAJ7620 IIC 通信
    Python中assert的使用
    Python中循环的使用
    Linux 生成指定大小文件
    SVN不显示log 显示1970年问题
    阿里云 CS实例 开机自运行脚本文件
    生成UDS安全算法DLL文件
  • 原文地址:https://www.cnblogs.com/ivantang/p/4049674.html
Copyright © 2020-2023  润新知