zoukankan      html  css  js  c++  java
  • gawk

    gawk

    虽然sed编辑器是非常方便自动修改文本文件的工具,但其也有自身的限制。通常你需要一个用来处理文件中的数据的更高级工具,它能提供一个类编程环境来修改和重新组织文件中的数据。这正是gawk能够做到的。

    gawk程序是Unix中的原始awk程序的GNU版本。gawk程序让流编辑迈上了一个新的台阶,它提供了一种编程语言而不只是编辑器命令。在gawk编程语言中,你可以做下面的事情:
     定义变量来保存数据;
     使用算术和字符串操作符来处理数据;
     使用结构化编程概念(比如if-then语句和循环)来为数据处理增加处理逻辑;
     通过提取数据文件中的数据元素,将其重新排列或格式化,生成格式化报告。
    gawk命令格式
    gawk程序的基本格式如下:
    gawk程序脚本用一对花括号来定义。
    由于gawk命令行假定脚本是单个文本字符串,你还必须将脚本放到单引号中。
    gawk options program file
    gawk '{print "Hello World!"}'
    -F fs 指定行中划分数据字段的字段分隔符
    -f file 从指定的文件中读取程序
    -v var=value 定义gawk程序中的一个变量及其默认值
    -mf N 指定要处理的数据文件中的最大字段数
    -mr N 指定数据文件中的最大数据行数
    -W keyword 指定gawk的兼容模式或警告等级
    使用数据字段变量
    使用数据字段变量
    gawk的主要特性之一是其处理文本文件中数据的能力。它会自动给一行中的每个数据元素分配一个变量。默认情况下,gawk会将如下变量分配给它在文本行中发现的数据字段:
     $0代表整个文本行;
     $1代表文本行中的第1个数据字段;
     $2代表文本行中的第2个数据字段;
     $n代表文本行中的第n个数据字段。
    gawk -F: '{print $1}' /etc/passwd
    #指定分割符为: 然后过滤第一列字符

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

    [root@localhost advanced_shell_script]# echo "my name is tom" |gawk '{$4="robin";print $0}' 
     my name is robin
    #多个命令用; 分隔,$0 代表整个字符串。定义的字符 robin 要用""

     从文件中读取程序

    [root@localhost gawk]# cat test1.gawk 
    {print $1 "'s home directory is" $6}
    [root@localhost gawk]# gawk -F: -f test1.gawk /etc/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

     多行命令

    [root@localhost gawk]# cat test1.gawk 
    {print $1 "'s home directory is" $6}
    {print $1}
    [root@localhost gawk]# gawk -F: -f test1.gawk /etc/passwd
    root's home directory is/root
    root
    bin's home directory is/bin
    bin

    或者

    [root@localhost gawk]# cat test1.gawk 
    text="'s home directory is"
    {print $1  text $6}
    [root@localhost gawk]# gawk -F: -f test1.gawk /etc/passwd
    root:x:0:0:root:/root:/bin/bash
    root's home directory is/root

     在处理数据前运行脚本

    [root@localhost gawk]# gawk 'BEGIN {print "The data file contents"}{print $0}' /etc/fstab 
    The data file contents
    
    #
    # /etc/fstab
    # Created by anaconda on Tue Feb 26 18:42:10 2019
    #
    # Accessible filesystems, by reference, are maintained under '/dev/disk'

     在处理数据后运行脚本

    [root@localhost gawk]# gawk 'BEGIN {print "hehe"} 
    > {print $0}
    > END {print "haha"}' data1
    hehe
    test text
    haha
    [root@localhost gawk]# 

     使用模式

    正则表达式

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

    匹配操作符

    匹配操作符(matching operator)允许将正则表达式限定在记录中的特定数据字段。匹配操作符是波浪线(~)。可以指定匹配操作符、数据字段变量以及要匹配的正则表达式。
    [root@localhost gawk]# gawk 'BEGIN{FS=" "}$1 ~ /^123/{print $1}' data1
    123
    [root@localhost gawk]# gawk -F: '$1 ~ /^zhengyue/{print $1,$NF}' /etc/passwd
    zhengyue /bin/bash
    [root@localhost gawk]# 

    数学表达式

    可以使用任何常见的数学比较表达式。
     x == y:值x等于y。
     x <= y:值x小于等于y。
     x < y:值x小于y。
     x >= y:值x大于等于y。
     x > y:值x大于y。
    也可以对文本数据使用表达式,但必须小心。跟正则表达式不同,表达式必须完全匹配。数据必须跟模式严格匹配。

    查看passwd 文件中属组是root 的用户

    [root@localhost gawk]# gawk -F: '$4 == 0{print $0}' /etc/passwd
    root:x:0:0:root:/root:/bin/bash
    sync:x:5:0:sync:/sbin:/bin/sync
    shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
    halt:x:7:0:halt:/sbin:/sbin/halt
    operator:x:11:0:operator:/root:/sbin/nologin
    [root@localhost gawk]# 

    gawk 结构化命令

      if 语句

    if (condition) 
     statement1
    [root@localhost gawk]# cat data3
    10
    20
    30
    [root@localhost gawk]# gawk '{
    if ($1>10)
    {
    x = $1 * 2
    print x
    }
    }' data3
    40
    60
    [root@localhost gawk]# 
    [root@localhost gawk]# cat data3
    10
    20
    30
    [root@localhost gawk]# gawk '{
    if ($1>10)
    {
    x = $1 * 2
    print x
    } else
    {
    x = $1 / 2
    print x
    }}' data3
    5
    40
    60
    [root@localhost gawk]# 

    while 循环语法

    [root@localhost gawk]# cat data4
    130 120 135 
    160 113 140 
    145 170 215
    [root@localhost gawk]# gawk '{
    total = 0
    i = 1
    while (i < 4)
    {
    total += $i
    i++
    }
    avg = total / 3
    print "Average:", avg
    }' data4
    Average: 128.333
    Average: 137.667
    Average: 176.667
    [root@localhost gawk]# 
    while语句会遍历记录中的数据字段,将每个值都加到total变量上,并将计数器变量i增值。
    当计数器值等于4时,while的条件变成了FALSE,循环结束,然后执行脚本中的下一条语句。
    这条语句会计算并打印出平均值。这个过程会在数据文件中的每条记录上不断重复。

    do-while 语句

    do-while语句类似于while语句,但会在检查条件语句之前执行命令。下面是do-while语句的格式。
    do 
    { 
     statements 
    } while (condition)
    [root@localhost gawk]# cat data4
    130 120 135 
    160 113 140 
    145 170 215
    [root@localhost gawk]# gawk '{         #正常是while ,,,do,,,done 这个流程, do while  理解就是先执行一遍循环体的内容,然后进行判断。符合就继续执行do ,不符合就执行后续的命令, 
    total = 0                  #这里的 print total 是在循环体外执行的, 把 do while 看成 while do 然后先执行 do 就好理解了
    i = 1
    do
    {
    total += $i
    i++
    } while (total < 150)
    print total }' data4
    250
    160
    315
    [root@localhost gawk]# 

    for 语句

    for语句是许多编程语言执行循环的常见方法。gawk编程语言支持C风格的for循环。
    for( variable assignment; condition; iteration process) 
    将多个功能合并到一个语句有助于简化循环。
    [root@localhost gawk]# cat data4
    130 120 135 
    160 113 140 
    145 170 215
    [root@localhost gawk]#  gawk '{ 
     total = 0 
     for (i = 1; i < 4; i++) 
     { 
     total += $i 
     } 
     avg = total / 3 
     print "Average:",avg 
     }' data4
    Average: 128.333
    Average: 137.667
    Average: 176.667
    [root@localhost gawk]# 

    内建函数

    数学函数

    gawk             数学函数
    函 数            描 述
    atan2(x, y)       x/y的反正切,x和y以弧度为单位
    cos(x)            x的余弦,x以弧度为单位
    exp(x)            x的指数函数
    int(x)            x的整数部分,取靠近零一侧的值
    log(x)            x的自然对数
    rand( )           比0大比1小的随机浮点值
    sin(x)            x的正弦,x以弧度为单位
    sqrt(x)           x的平方根
    srand(x)          为计算随机数指定一个种子值

     

    字符串函数

    gawk                  字符串函数
    函 数               描 述
    asort(s [,d])      将数组s按数据元素值排序。索引值会被替换成表示新的排序顺序的连续数字。另外如果指定了d,则排序后的数组会存储在数组d中
    asorti(s [,d])     将数组s按索引值排序。生成的数组会将索引值作为数据元素值,用连续数字索引来明排序顺序。另外如果指定了d,排序后的数组会存储在数组d中
    gensub(r, s, h [, t]) 查找变量$0或目标字符串t(如果提供了的话)来匹配正则表达式r。如果h是一个以g或G开头的字符串,就用s替换掉匹配的文本。如果h是一个数字,它表示要替换掉第处r匹配的地方
    gsub(r, s [,t])    查找变量$0或目标字符串t(如果提供了的话)来匹配正则表达式r。如果找到了,就全部替换成字符串s
    index(s, t)       返回字符串t在字符串s中的索引值,如果没找到的话返回0
    length([s])       返回字符串s的长度;如果没有指定的话,返回$0的长度
    match(s, r [,a])  返回字符串s中正则表达式r出现位置的索引。如果指定了数组a,它会存储s中匹配则表达式的那部分22.6 内建函数 489 
    
    split(s, a [,r])  将s用FS字符或正则表达式r(如果指定了的话)分开放到数组a中。返回字段的总数sprintf(format, variables) 用提供的format和variables返回一个类似于printf输出的字符串
    sub(r, s [,t])    在变量$0或目标字符串t中查找正则表达式r的匹配。如果找到了,就用字符串s替换掉第一处匹配
    substr(s, i [,n])  返回s中从索引值i开始的n个字符组成的子字符串。如果未提供n,则返回s剩下的部分
    tolower(s)        将s中的所有字符转换成小写
    toupper(s)        将s中的所有字符转换成大写
    [root@localhost gawk]# gawk 'BEGIN{x = "testing"; print toupper(x);print length(x)}'   #常用方式
    TESTING
    7

    时间函数

    gawk 的时间函数
    函 数                              描 述
    mktime(datespec)              将一个按YYYY MM DD HH MM SS [DST]格式指定的日期转换成时间戳值①
    strftime(format [,timestamp]) 将当前时间的时间戳或timestamp(如果提供了的话)转化格式化日期(采用shell函数date()的格式)
    systime( )                   返回当前时间的时间戳
    [root@localhost gawk]# gawk 'BEGIN{
    date = systime()
    print date
    day = strftime("%A , %B ,%d , %Y",date)
    print day
    }'
    1555921121
    星期一 , 四月 ,22 , 2019
    [root@localhost gawk]# 
  • 相关阅读:
    软件开发工具-4
    软件开发工具-3
    软件开发工具-2
    软件开发工具-1
    2020年06月02日_Node_exporter的docker部署方式监控网络不准确问题
    DELL OpenManage Server Administrator安装及使用
    yum下载rpm包和依赖包到指定目录(且不安装)
    诡异的docker网络问题解决
    nextcloud新实例安装时一直在登录页面转圈圈
    洛谷-P4414 [COCI2006-2007#2] ABC
  • 原文地址:https://www.cnblogs.com/zy09/p/10722030.html
Copyright © 2011-2022 走看看