目录
62. 变量
64. 算术操作符
65. 字符串操作符
66. 赋值操作符
67. 比较操作符
68. 正则表达式操作符
62. 变量
 Awk  变量以字母开头,后续字符可以是数字、字母、或下划线。关键字不能用作  awk  变量。  
 
 不像其他编程语言, awk  变量可以直接使用而不需事先声明。如果要初始化变量,最好在  
 
 BEGIN  区域内作,它只会执行一次。  
 
 Awk  中没有数据类型的概念,一个  awk  变量是  number  还是  string  取决于该变量所处的上下  
 
 文。  
 
 employee-sal.txt  示例文件  
 
 emploeyee-sal.txt  以逗号作为字段分隔符,包含五个雇员的信息,格式如下 :  
 
 employee-numer,employee-name,employee-title,salary  
 
 创建下面文件 :  
 
 $ vi employee-sal.txt  
 
 101,John Doe,CEO,10000  
 
 102,Jason Smith,IT Manager,5000  
 
 103,Raj Reddy,Sysadmin,4500  
 
 104,Anand Ram,Developer,4500  
 
 105,Jane Miller,Sales Manager,3000  
 
 下面的例子将教你如何在  awk  中创建和使用自己的变量,该例中, ”total” 便是用户建立的用  
 
 来存储公司所有雇员工资总和的变量。  
 
 $ vi total-company-salary.awk  
 
 BEGIN {  
 
 FS=",";  
 
 total=0;  
 
 }  
 
 {  
 
 print $2 "'s slary is: " $4;  
 
 total=total+$4  
 
 }  
 
 END {  
 
 print "---\nTotal company salary =$"total;  
 
 }  
 
 $ awk -f total-company-salary.awk employee-sal.txt  
 
 John Doe's slary is: 10000  
 
 Jason Smith's slary is: 5000  
 
 Raj Reddy's slary is: 4500Anand Ram's slary is: 4500  
 
 Jane Miller's slary is: 3000  
 
 ---  
 
 Total company salary =$27000  
 
 63.  一元操作符  
 
 只接受单个操作数的操作符叫做一元操作符。 
 
 
 
 下面的例子使用取反操作 :  
  $ awk -F, '{print -$4}' employee-sal.txt  
  -10000  
  -5000  
  -4500  
  -4500  
  -3000  
  下面的例子演示取正、取反操作符对文件中存放的复数的作用:  
  $ vi negative.txt  
  -1  
  -2  
  -3  
  $ awk '{print +$1}' negative.txt  
  -1  
  -2  
  -3  
  $ awk '{print -$1}' negative.txt  
  1  
  2  
  3  
  自增和自减操作  
  自增和自减改变变量的值,它可以在使用变量“之前”或“之后”改变变量的值。在表达式  
  中,使用的可能是改变前的值 (post) 或改变后的值 (pre). 使用改变后的变量值 (pre) 即是在变量前面加上 ++( 或 --) ,首先把变量的值加  1( 或减  1) ,然后  
  把改变后的值应用到表达式的其它操作中。  
  使用改变前的变量值 (post) 即是在变量后面加上 ++( 或 --) ,首先把变量值应用到表达式中进行  
  计算,然后把变量的值加  1( 或减  1) 。  
  Pre  自增示例 :  
  $ awk -F, '{print ++$4}' employee-sal.txt  
  10001  
  5001  
  4501  
  4501  
  3001  
  Pre  自减示例 :  
  $ awk -F, '{print --$4}' employee-sal.txt  
  9999  
  4999  
  4499  
  4499  
  2999  
  Post  自增示例 :  
  ( 因为 ++  在  print  语句中,所以变量的原始值被打印 )  
  $ awk -F, '{print $4++}' employee-sal.txt  
  10000  
  5000  
  4500  
  4500  
  3000  
  Post  自减示例 :  
  ( 因为 ++ 是单独语句,所以自增后的值被打印 )  
  $ awk -F, '{$4++;print $4}' employee-sal.txt  
  10001  
  5001  
  4501  
  4501  
  3001  
  Post  自减示例 :  
  ( 因为 — 在  print  语句中,所以变量原始值被打印 )  
  $ awk -F, '{print $4--}' employee-sal.txt  
  10000 
  5000  
  4500  
  4500  
  3000  
  Post  自减示例 :  
  ( 因为 — 在单独语句中,所以自减后的值被打印 )  
  $ awk -F, '{$4--;print $4}' employee-sal.txt  
  9999  
  4999  
  4499  
  4499  
  2999  
  下面是一个有用的例子,显示所有登录到  shell  的用户数,即哪些用户可以登录  shell  并获得  
  命令提示符。  
  使用算后自增运算符 ( 尽管变量值只到  END  区域才打印出来,算前自增仍会产生同  
  样的结果 )  
  脚本的  body  区域包含一个模式匹配,因此只有最后一个字段匹配模式 /bin/bash  时,  
  body  的代码才会执行  
  提示 : 正则表达式应该包含在 // 之间,但如果正则表达式中的 / 必须转移,以避免被  
  解析为正则表达式的结尾  
  当有匹配到模式的行时,变量  n  的值增加  1 ,最终的值在  END  区域打印出来。  
   打印所有可登陆  shell  的用户总数 :  
  $ awk -F':' '$NF ~ /\/bin\/bash/ { n++ }; END { print n }' /etc/passwd  
  2  
 64. 算术操作符
 需要两个操作数的操作符,成为二元操作符。 Awk  中有多种基本二元操作符 ( 如算术操作符、  
  字符串操作符、赋值操作符,等等 ) 。  
  下面是算术运算操作符 : 
  
 
 
 下面的例子展示 +,-,*,/ 的用法 . 下面例子完成两个事情 :  
  1.  将每件单独的商品价格减少  20%  
  2.  将每件单独的商品的数量减少  1  
  创建并运行  awk  算术运算脚本 :  
  $ vi arithmetic.awk  
  BEGIN {  
  FS=",";  
  OFS=",";  
  item_discount=0;  
  }  
  {  
  item_discount=$4*20/100;  
  print $1,$2,$3,$4-item_discount,$5-1;  
  }  
  $ awk -f arithmetic.awk items.txt  
  101,HD Camcorder,Video,168,9  
  102,Refrigerator,appliance,680,1  
  103,MP3 Player,Audio,216,14  
  104,Tennis Racket,Sports,152,19  
  105,Laser Printer,Office,380,4  
  下面的例子只打印偶数行。打印前会检查行号是否能被  2  整除,如果整除,则执行默认的操  
  作 ( 打印整行 ).  
  取模运算演示 :  
  $ awk 'NR % 2 == 0' items.txt  
  102,Refrigerator,appliance,850,2  
  104,Tennis Racket,Sports,190,20  
 65. 字符串操作符
 ( 空格 ) 是连接字符串的操作符。  
  下面例子中,有三处使用了字符串连接。在语句 ”string3=string1 string2” 中, string3  包含了  
  string1  和  string2  连接后的内容。每个  print  语句都把一个静态字符串和  awk  变量做了连接。  
  ᨀ示 : 这个操作符解释了为什么在打印多个变量时,如果要使用  OFS  分隔每个字段,就需要  
  在  print  语句中用逗号分隔每个变量。如果没有使用逗号分隔,那么会把所有值连接成一个  
  字符串。 $ cat string.awk  
  BEGIN {  
  FS=",";  
  OFS=",";  
  string1="Audio";  
  string2="Video";  
  numberstring="100";  
  string3=string1 string2;  
  print "Concatenate string is:" string3;  
  numberstring=numberstring+1;  
  print "String to number:" numberstring;  
  }  
  $ awk -f string.awk items.txt  
  Concatenate string is:AudioVideo  
  String to number:101  
 66. 赋值操作符
 与其他大部分编程语言一样, awk  使用  =  作为赋值操作符。和  C  语言一样, awk  支持赋值  
  的缩写方式。 
 
 
 
 下面的例子演示如何使用赋值 :  
  $ cat assignment.awk  
  BEGIN {  
  FS=",";  
  OFS=",";  
  total1 = total2 = total3 = total4 = total5 = 10;  
  total1 += 5; print total1;  
  total2 -= 5; print total2;  
  total3 *= 5; print total3;  
  total4 /= 5; print total4;  
  total5 %= 5; print total5;  
  } $ awk -f assignment.awk  
  15  
  5  
  50  
  2  
  0  
  下面的例子使用加法赋值的缩写形式 .  
  显示所有商品的清单:  
  $ awk -F ',' 'BEGIN { total=0 } { total += $5 } END {print "Total Quantity: " total }' items.txt  
  Total Quantity: 52  
  下面的例子统计输入文件中所有的字段数。 Awk  读取每一行,并把字段数量增加到变量  total  
  中。然后在  END  区域打印该变量。  
  $ awk -F ',' 'BEGIN { total = 0 } { total += NF } END { print total }' items.txt  
  25  
 67. 比较操作符
 
 
 提示:下面的例子,如果不指定操作, awk  会打印符合条件的整条记录。  
   打印数量小于等于临界值 5 的商品信息:  
  $ awk -F ',' '$5 <= 5' items.txt  
  102,Refrigerator,appliance,850,2  
  105,Laser Printer,Office,475,5  
   打印编号为 103 的商品信息:  
  $ awk -F "," '$1 == 103' items.txt  
  103,MP3 Player,Audio,270,15  
  提示 : 不要把 ==( 等于 ) 和 =( 赋值 ) 搞混了。 
   打印编号为 103 的商品的描述信息 :  
  $ awk -F "," '$1 == 103 { print $2}' items.txt  
  MP3 Player  
   打印除 Video 以外的所有商品:  
  $ awk -F "," '$3 != "Video"' items.txt  
  102,Refrigerator,appliance,850,2  
  103,MP3 Player,Audio,270,15  
  104,Tennis Racket,Sports,190,20  
  105,Laser Printer,Office,475,5  
   和上面相同,但只打印商品描述信息:  
  $ awk -F "," '$3 != "Video" { print $2}' items.txt  
  Refrigerator  
  MP3 Player  
  Tennis Racket  
  Laser Printer  
   使用&&比较两个条件,打印价钱低于 900 并且数量小于等于临界值 5 的商品信息:  
  $ awk -F "," '$4 < 900 && $5 <= 5' items.txt  
  102,Refrigerator,appliance,850,2  
  105,Laser Printer,Office,475,5  
   和上面相同,但只打印商品描述信息:  
  $ awk -F "," '$4 < 900 && $5 <= 5 {print $2}' items.txt  
  Refrigerator  
  Laser Printer  
  使用||比较两个条件,打印价钱低于 900 或者数量小于等于临界值 5 的商品信息:  
  $ awk -F "," '$4 < 900 || $5 <= 5' items.txt  
  101,HD Camcorder,Video,210,10  
  102,Refrigerator,appliance,850,2  
  103,MP3 Player,Audio,270,15  
  104,Tennis Racket,Sports,190,20  
  105,Laser Printer,Office,475, 
   和上面相同,但只打印商品描述信息:  
  $ awk -F "," '$4 < 900 || $5 <= 5 {print $2}' items.txt  
  HD Camcorder  
  Refrigerator  
  MP3 Player  
  Tennis Racket  
  Laser Printer 下面例子使用 > 条件,打印 /etc/password  中最大的  UID( 以及其所在的整行 ) 。 Awk  把最大的  
  UID( 第  3  个字段 ) 放在变量  maxuid  中,并且把包含最大  UID  的行复制到变量  maxline  中。循  
  环执行完后,打印最大的  UID  和其所在的行。  
   $ awk -F ':' '$3 > maxuid { maxuid = $3; maxline = $0 } END { print maxuid,maxline }' /etc/passwd  
  65534 nobody:x:65534:65533:nobody:/var/lib/nobody:/bin/bash  
   打印/etc/passwd 中 UID 和 GROUP ID 相同的用户信息  
  $ awk -F ':' '$3 == $4' /etc/passwd  
  root:x:0:0:root:/root:/bin/bash  
   打印/etc/passwd 中 UID >= 100 并且用户的 shell 是/bin/sh 的用户:  
  $ awk -F ':' '$3 >= 100 && $NF ~ /\/bin\/sh/ ' /etc/passwd  
  mygame:x:2300:0::/opt/game:/bin/sh  
   打印 /etc/passwd  中没有注释信息 ( 第  5  个字段 ) 的用户 :  
  mkey3g@mkey:/opt/mkey3g/ec> awk -F ':' '$5 == ""' /etc/passwd  
  mfs:x:2001:1000::/home/mfs:/bin/nologin 
 
68. 正则表达式操作符

 使用 == 时, awk  检查精确匹配。 下面的例子不会打印任何信息,因为  items.txt  中,没有任  
  何一条记录的第二个字段精确匹配关键字 ”Tennis”,”Tennis Racket” 不是精确匹配。  
   打印第二个字段为 ”Tennis” 的记录 :  
  $ awk -F "," '$2 == "Tennis"' items.txt  
   当使用 ~ 时, awk  执行模糊匹配,检索 ” 包含 ” 关键字的记录 .  
  打印第二个字段包含 ”Tennis” 的行 :  
  $ awk -F "," '$2 ~ "Tennis"' items.txt  
  104,Tennis Racket,Sports,190,20  
  !~  对应  ~, 即不匹配 .  
   打印第二个字段不包含 ”Tennis” 的行 :  
  $ awk -F "," '$2 !~ "Tennis"' items.txt  
  101,HD Camcorder,Video,210,10  
  102,Refrigerator,appliance,850,2  
  103,MP3 Player,Audio,270,15  
  105,Laser Printer,Office,475,5 
   下面的例子打印  shell  为 /bin/bash  的用户的总数,如果最后一个字段包含 ”/bin/bash”, 则变量  
  n  增加  1  
  $ awk -F ':' '$NF ~ /\/bin\/bash/ { n++ } END { print n }' /etc/passwd  
  13 
 
资料来源于《SedandAwk101Hacks》,大家有兴趣可以买一本,也可以关注我,我更新完它。
曾经,我花费大半月将它们跑完,现在啥都忘了,还是要常用。
只为学习交流,不为获利,侵权联系立删。