unijun 发表于 2018-8-21 12:54:04

2.3.1.shell awk 入门

  awk:好用的数据处理工具

  awk 也是一个非常棒的数据处理工具!sed 常常用于一整个行的处理, awk 则比较倾向于一行当中分成数个『栏位』(或者称为一个域,也就是一列)来处理。因此,awk 相当的适合处理小型的数据数据处理呢!awk 通常运行的模式是这样的:
# awk '条件类型1{动作1} 条件类型2{动作2} ...' filename  awk 后面接两个单引号并加上大括号 {} 来配置想要对数据进行的处理动作。 awk 可以处理后续接的文件,也可以读取来自前个命令的 standard output 。 但如前面说的, awk 主要是处理『每一行的栏位内的数据』,而默认的『栏位的分隔符号为 "空白键" 或 "键" 』!举例来说,我们用 last 可以将登陆者的数据取出来,结果如下所示:
# last -n 5NR>=2{total=$2+$3+$4
  
> printf "%10s %10d %10d %10d %10.2f\n",$1,$2,$3,$4,total}'
  
      Name      1st      2nd      3th      Total
  
   VBird      23000      24000      25000   72000.00
  
    DMTsai      21000      20000      23000   64000.00
  
   Bird2      43000      42000      41000126000.00
  

  
   上面的例子有几个重要事项应该要先说明的:
  
awk 的命令间隔:所有 awk 的动作,亦即在 {} 内的动作,如果有需要多个命令辅助时,可利用分号『;』间隔, 或者直接以 按键来隔开每个命令,例如上面的范例中,鸟哥共按了三次 喔!
  
逻辑运算当中,如果是『等於』的情况,则务必使用两个等号『==』!
  
格式化输出时,在 printf 的格式配置当中,务必加上 \n ,才能进行分行!
  
与 bash shell 的变量不同,在 awk 当中,变量可以直接使用,不需加上 $ 符号。
  
利用 awk 这个玩意儿,就可以帮我们处理很多日常工作了呢!真是好用的很~ 此外, awk 的输出格式当中,常常会以 printf 来辅助,所以, 最好你对 printf 也稍微熟悉一下比较好啦!另外, awk 的动作内 {} 也是支持 if (条件) 的喔! 举例来说,上面的命令可以修订成为这样:
  
# cat pay.txt | \
  
> awk '{if(NR==1) printf "%10s %10s %10s %10s %10s\n",$1,$2,$3,$4,"Total"}
  
> NR>=2{total=$2+$3+$4
  
> printf "%10s %10d %10d %10d %10.2f\n",$1,$2,$3,$4,total}'
  
      Name      1st      2nd      3th      Total
  
   VBird      23000      24000      25000   72000.00
  
    DMTsai      21000      20000      23000   64000.00
  
   Bird2      43000      42000      41000126000.00
  你可以仔细的比对一下上面两个输入有啥不同~从中去了解两种语法吧!我个人是比较倾向於使用第一种语法, 因为会比较有统一性啊! ^_^
  学习了awk的基本知识,现在来做一些练习加深一下印象。
  假设我们有这样一个待处理的文件"grade.txt":
  M.Tansley   05/99   48311   Green   8   40   44
  J.Lulu   06/99   48317   green   9   24   26
  P.Bunny   02/99   48   Yellow   12   35   28
  J.Troll   07/99   4842   Brown-3   12   26   26
  L.Tansley   05/99   4712   Brown-2   12   30   28
  #打印整个文件
  # awk '{print $0}' grade.txt
  M.Tansley   05/99   48311   Green   8   40   44
  J.Lulu   06/99   48317   green   9   24   26
  P.Bunny   02/99   48   Yellow   12   35   28
  J.Troll   07/99   4842   Brown-3   12   26   26
  L.Tansley   05/99   4712   Brown-2   12   30   28
  #打印第一和第四个域
  # awk '{print $1,$4}' grade.txt
  M.Tansley Green
  J.Lulu green
  P.Bunny Yellow
  J.Troll Brown-3
  L.Tansley Brown-2
#打印表头  # awk 'BEGIN{print "Name      Belt\n-----------------"}
  {print $1,$4}' grade.txt
  Name      Belt
  -----------------
  M.Tansley Green
  J.Lulu green
  P.Bunny Yellow
  J.Troll Brown-3
  L.Tansley Brown-2
  正则表达式相关:
  为使一域号匹配正则表达式,使用符号‘~’后紧跟正则表达式,也可以用 i f语句。awk中if后面的条件用()括起来。
  #下面代码打印$4 包含 Brown 的行
  # awk '$4~/Brown/{print $0}' grade.txt
  J.Troll   07/99   4842   Brown-3   12   26   26
  L.Tansley   05/99   4712   Brown-2   12   30   28
  #非精确匹配
  # awk '$3~/48/{print $0}' grade.txt
  M.Tansley   05/99   48311   Green   8   40   44
  J.Lulu   06/99   48317   green   9   24   26
  P.Bunny   02/99   48   Yellow   12   35   28
  J.Troll   07/99   4842   Brown-3   12   26   26
  
  #精确匹配
  
  # awk '$3=="48"{print $0}' grade.txt
  P.Bunny   02/99   48   Yellow   12   35   28
  
  #不匹配 使用 ‘!~’
  # awk '$0!~/Brown/' grade.txt
  M.Tansley   05/99   48311   Green   8   40   44
  J.Lulu   06/99   48317   green   9   24   26
  P.Bunny   02/99   48   Yellow   12   35   28
  
  
  # awk '$4!="Brown-2"{print$0}' grade.txt
  M.Tansley   05/99   48311   Green   8   40   44
  J.Lulu   06/99   48317   green   9   24   26
  P.Bunny   02/99   48   Yellow   12   35   28
  J.Troll   07/99   4842   Brown-3   12   26   26
  
  #小于
  # awk '$6
页: [1]
查看完整版本: 2.3.1.shell awk 入门