shellNote--day15

shellNote

day15

gawk程序编辑器

在gawk跟sed一样,可以进程流编辑,相比来说更加强大,他提供一种类编程的环境来修改和重组文件的数据;

命令格式:

gawk options program file

gawk选项:

选项描述
-F fs指定行中划分数据字段的字段分隔符
-f file从指定的文件中读取程序
-v var=value定义gawk程序中的一个变量及其默认值
-mf N指定要处理的数据文件中的最大字段数
-mr N指定数据文件中的最大数据行数
-W keyword指定gawk的兼容模式或警告等级
  • 命令行读取程序脚本

    由于gawk命令行假定脚本是单个文本字符串,所以还需要将脚本放到单引号中;

    $ gawk '{print "Hello World!"}'

    运行时,不会输出任何信息,由于没有给gawk程序输入数据流,

    这时gawk会等待STDIN接受数据,当输入一行并按下回车键,gawk程序会对该数据运行一遍程序脚本,

    这个例子中,就将想STDOUT输出Hello World!

    结束这个例子程序,需要在STDIN中输入EOF,组合键Ctrl-D可以产出EOF字符;

  • 使用数据字段变量

    gawk会自动给一行中的数据元素分配一个变量,默认情况下:

    • $0代表整个文本行;
    • $1代表文本行中的第一个数据字段;
    • $2代表文本行中的第二个数据字段;
    • $n代表文本行中的第n个数据字段;

    gawk默认的字段分隔符是任意的空白符(空格或制表符);

    可以通过-F来指定其他分隔符;

    $ gawk -F: '{print $1}' /etc/passed
    root
    bin
    daemon
    adm
    ......
    
  • 脚本中使用多个命令

    gawk可以使用多个命令组合成一个正常的程序;

    只需在命令之间放个分号即可;

    $ echo "My name is Rich" | gawk '{$4="Damon"; print $0}'
    My name is Damon
    $
    
  • 从文件中读取程序

    使用-f选项来指定gawk的脚本文件;

    在文件中指定多条命令的话,可以将没条命令放一行,这样就需要用分号来分隔;

    $ cat script.gawk
    {
    text = "'s home directory is "
    print $1 text $6
    }
    $ gawk -F: -f script.gawk /etc/passwd
    root's home directory is /root
    bin's home directory is /bin
    ......
    
  • 处理数据前运行脚本

    gawk可以在处理数据脚本执行前,运行一段脚本;

    BEGIN关键字来定义这段脚本;

    gawk 'BEGIN {programs}'

    $ gawk 'BEGIN {print "Hello World"}'
    Hello World
    $
    

    BEGIN脚本中,有一个特殊变量FS,可以用来代替-F选项来定义字段分隔符;

  • 处理数据后运行脚本

    gawk可以在处理数据脚本执行后,运动一段脚本;

    END关键字来定义这段脚本;

    一段完整的gawk格式:

    $ gawk 'BEGIN {program1s}
    > {program2s}
    > END {program3s}' dataInput.txt
    
  • 变量

    • 内建变量

      • 字段和记录分隔符变量

        数据字段变量是符号$和字段的位置值来引用的;

        数据字段是由字段分隔符来划定的;

        默认情况下字段分隔符是空白符;

        • FILELDWIDTHS: 由空格分隔的一列数字,定义了每个数据字段确切宽度;

          可以不依靠字段分隔符来读取记录;

          一旦FILELDWIDTHS变量被设置,FS变量将被忽略;

          $ cat data
          1005.3247596.37
          $ gawk 'BEGIN{FILELDWIDTHS="3 5 2 5"} {print $1,$2,$3,$4}' data
          100 5.324 75 96.37
          
        • FS: 输入字段分隔符;

        • OFS: 输出字段分隔符;

          默认情况下,OFS设成一个空格;

          print $1,$2,$3

          会输出为:

          field1 field2 field3

          $ cat data
          data1,data2,data3
          $ gawk 'BEGIN{FS=","; OFS="-"} {print $1,$2,$3}' data
          data1-data2-data3
          
        • RS: 输入记录分隔符;

        • ORS: 输出记录分隔符;

          RS和ORS定义了如何处理数据流的字段;

          默认情况下,RS和ORS设为换行符;

          $ cat data
          Damon BIAN
          WUHAN HUBEI
          tel:123456
          
          Tony WANG
          RIZHAO SHANDONG
          tel:234567
          
          Yellow HUANG
          MACHENG HUBEI
          tel:345678
          $ gawk 'BEGIN{FS="\n"; RS=""} {print $1,$3}' data
          Damon BIAN tel:123456
          Tony WANG tel:234567
          Yellow HUANG tel:345678
          $
          
      • 数据变量

        • ARGC: 当前命令行参数个数;

        • ARGIND: 当前文件在ARGV中的位置;

        • ARGV: 包含命令行参数的数组;

          ARGC和ARGV变量可以获得命令行参数的总数以及他们的值;

          $ gawk 'BEGIN{print ARGC,ARGV[1]}' data
          2 data
          

          gawk不会将程序脚本当做命令行参数,这里面包含gawk命令和data参数两个;

          ARGV数字从0开始;

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

        • ENVIRON: 当前shell环境变量及其值组成的关联数组;

          使用ENVIRON来提取shell的环境变量,用文本来作为数组的索引值;

          $ gawk '
          > BEGIN { 
          > print ENVIRON["HOME"]
          > print ENVIRON["PATH"]
          > } '
          /home/damon
          /usr/local/bin:/bin:......
          $
          
        • ERRNO: 当读取或关闭输入文件发生错误时的系统错误号;

        • FILENAME: 用作gawk输入数据的数据文件的文件名;

        • IGNORECASE: 设成非零值时,忽略gawk命令中出现的字符串的字符大小写;

        • NF: 数据文件中的字段总数;

          可以使用其方便的指定记录的最后一个数据字段;

          $ gawk 'BEGIN{FS=":"; OFS=":"} {print $1,$NF}' /etc/passwd
          damon:/bin/bash
          rich:/bin/bash
          ......
          $
          
        • NR: 已处理的输入记录数;

        • FNR: 当前数据文件中的数据行数;

          NR和FNR在处理一个文件时,其实是一样的;

          当处理两个文件或以上时,FNR的值会在处理新文件时重置,NR的值则会继续计数;

          $ cat data
          data11 data12 data13
          data21 data22 data23
          data31 data32 data33
          $ gawk '
          > {print $1, "FNR="FNR, "NR="NR}
          > ' data data
          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
          $							
          
        • OFMT: 数字的输出格式,默认值为%.6 g

        • RLENGTH: 由match函数所匹配的子字符串的长度;

        • RSTART: 由match函数所匹配的子字符串的起始位置;

    • 自定义变量

      gawk可以自己定义表里,自定的表里可以是任意的字母,数字,下划线,但不能数字开头,并且区分大小写;

      • 脚本中赋值

        跟shell中赋值类似,直接使用赋值语句;

        $ gawk 'BEGIN{x=4; x=x * 2 + 3; print x}'
        11
        $
        

        gawk可以使用标准算数操作符,包括求余符号(%),幂运算符号(^或**);

      • 在命令行上赋值

        可以在gawk命令行来给程序的变量赋值;

        $ cat data
        data11 data12 data13
        data21 data22 data23
        data31 data32 data33
        $ cat script
        {print $n}
        $ gawk -f script n=2 data
        data12
        data22
        data23
        

        命令行参数定义的变量值,在BEGIN部分不可以使用;

        需要在BEGIN使用的话,需要在gawk命令加上-v选项,-v选项要放在脚本之前;

        $ cat script
        BEGIN{print n}
        {print $n}
        $ gawk -v n=2 -f script data
        2
        data11 data12 data13
        data21 data22 data23
        data31 data32 data33
        $			
        
  • 数组

    gawk使用的是关联数组,他的索引值可以是任意的文本字符串,类似于字典一样;

    • 定义数组变量

      格式: var[index] = element

      var是变量名,index是索引值,element是数据元素值;

      $ gawk 'BEGIN{
      > var["A"] = "apple"
      > var["B"] = "banana"
      > print var["A"]
      > }'
      apple
      $
      
    • 遍历数组

      遍历数组,使用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]

      $ 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在使用正则表达式时,需要出现在他要控制的程序脚本的左花括号前;

      $ cat data
      1122 3344
      2233 4455
      $ gawk '/11/{print $1}' data
      1122
      
    • 匹配操作符

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

      $1 ~ /^data/

      $1变量代表记录中的第一个字段,这个表达式会过滤第一个字段以data开头的文本的记录;

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

      另外可以使用!符号来排除正则表达式的匹配

      $1 !~ /expression/

      $ gawk -F: '$1 !~ /damon/{print $1,$NF}' /etc/passwd
      root /bin/bash
      bin /bin/sh
      ......
      
    • 数学表达式

      可以在匹配模式中使用数学表达式来过滤文本;

      可以使用的数学比较表达式:

      • x == y
      • x <= y
      • x < y
      • x >= y
      • x > y
      $ gawk -F: '$4 == 0 {print $1}' /etc/passwd
      root
      sync
      shutdown
      ......
      
  • 结构化命令

    • if语句

      格式:

      if (condition)
      	statement1
      
      if (condition)  
      {
      	statements
      }
      else
      {
      	statements
      }
      
    • while语句

      格式:

      while (condition)
      {
      	statements 
      }
      

      gawk同样支持break和continue语句;

    • do-while语句

      格式:

      do
      {
      	statements
      } while (condition)
      
    • for语句

      格式:

      for( variable assignment; condition ; iteration process) 
      {
      	statements
      }
      
  • 格式化打印-printf

    printf命令格式:

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

    跟c语言编程用法一样;

  • 数学函数

函数描述
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)为计算随机数指定一个种子值
  • 位操作函数
函数描述
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的按位异或运算
  • 字符串函数
函数描述
asort(s [,d])将数组s按数据元素值排序,索引值会被连续的数字代替,
如果指定了d,排序后的数组会存放在数组d中
asorti(s [,d])将数组按索引值排序,生成的数组会将索引值作为数据元素值,
用连续数组索引来表明排序顺序,同样d可以存放新数组
gensub(r, s, h [,t])查找变量$0或目标字符串t(如果提供了的话)来匹配正则表达式r。
如果h是一个以g或G开头的字符串,就用s替换掉匹配的文本。
如果h是一个数字,它表示要替换掉第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中匹配正则表达式的那部分
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中的所有字符转换成大写
  • 时间函数
函数描述
mktime(datespec)将一个按YYYY MM DD HH MM SS [DST]格式指定的日期转换成时间戳值
strftime(format[,timestamp])将当前时间的时间戳或timestamp(如果提供了的话)转化格式化日期(采用shell函数date()的格式)
systime( )返回当前时间的时间戳
$ gawk 'BEGIN{
> date = systime()
> day = strftime("%A, %B %d, %Y", date)
> print day
> }'
Friday, December 26, 2014
$
  • 自定义函数

    格式:

    function name([vars])
    {
    	statements
    }
    

    定义函数时,必须在出现的所有代码快之前(包含BEGIN代码块)

    使用函数库文件,可以在gawk命令时,使用-f选项来指定函数库文件;

    gawk -f functionLIB -f script datafile

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值