设为首页 收藏本站
查看: 979|回复: 0

shell脚本三剑客之awk命令

[复制链接]

尚未签到

发表于 2018-8-28 12:21:10 | 显示全部楼层 |阅读模式
  awk:
  测试用模版:
  M.Tansley 05/99 48311 Green   8  40 44.44
  J.Lulu    06/99 48317 green   9  24 2678.
  P.Bunnyaaa   02/99 48    Yellow  12 35 2658
  J.Troll   07/99 4842  Brown-3 12 26 266666
  L.Tansleyaaa 05/99 4712  Brown-2 12 30 44544
  模式和动作:
  最常用的动作是打印(print)也有较长的动作代码if和while和for,
  模式可以是任何条件语句或复合语句或正则表达式也包括两个特殊字段BEGIN和END。
  BEGIN的使用是在awk正式对文本做读取操作之前,END则是在awk在做完所有操作之后
  awk脚本的输入方法:
  脚本名(test.awk) 文件名(abc.txt)正规使用方法为方法一
  方法一:test.awk abc.txt
  方法二:test.awk < abc.txt
  方法三:abc.txt | test.awk
  awk使用时出现错误的原因:
  确保整个awk命令用单引号括起来。
  确保命令内所有引号成对出现。
  确保用花括号括起动作语句,用圆括号括起条件语句。
  可能忘记使用花括号,也许你认为没有必要,但awk不这样认为,将按之解释语法。
  NR:表示awk开始执行程序后所读取的数据行数
  例:[root@localhost awk]# awk '{print NR}' data.f
  1
  2
  3
  4
  5
  释:也可以在花括号前加入END字段,表示打印最后一行行数。
  $NF:最后一列数据
  例:[root@localhost awk]# awk '{print $NF}' data.f
  44.44
  2678.
  2658
  266666
  44544
  释:可以在花括号前加入END,表示打印最后一行的最后一列。
  保存输出:
  例:[root@localhost awk]# awk '{print $0}' data.f |tee wow
  M.Tansley 05/99 48311 Green   8  40 44.44
  J.Lulu    06/99 48317 green   9  24 2678.
  P.Bunnyaaa   02/99 48    Yellow  12 35 2658
  J.Troll   07/99 4842  Brown-3 12 26 266666
  L.Tansleyaaa 05/99 4712  Brown-2 12 30 44544
  释:"$0"打印全行,tee是将管道符前面的结果保存到wow文件中同时标准输出在屏幕上。
  打印报告头和结束尾:
  例:[root@localhost awk]# awk 'BEGIN {print "name     color\n------------------------"} {print $1,$4}' data.f
  name     color
  ------------------------
  M.Tansley Green
  J.Lulu green
  P.Bunnyaaa Yellow
  J.Troll Brown-3
  L.Tansleyaaa Brown-2
  释:”\n“另起一行
  例:[root@localhost awk]# awk 'BEGIN {print "name     color\n---------------"} {print $1,$4} END {print "\n-----------jieshu"}' data.f
  name     color
  --------------------
  M.Tansley Green
  J.Lulu green
  P.Bunnyaaa Yellow
  J.Troll Brown-3
  L.Tansleyaaa Brown-2
  ---------------jieshu
  [root@localhost awk]# awk 'BEGIN {print "name\tcolor"} {print $1"\t" $2}' data.f
  name    color
  M.Tansley       05/99
  J.Lulu  06/99
  P.Bunnyaaa      02/99
  J.Troll 07/99
  L.Tansleyaaa    05/99
  释:”\t“执行tab键
  正则表达式:
  在awk中正则表达式是使用斜线来表示的,例如,查找Green字符可以这样表达"/Green/",在awk中可以使用的元字符有如下;
  \ :转意符号,如果在命令中有特殊符号,但是不想用特殊符号的功能只需要在特殊符号前加转义符号。
  . :一位任意数
  [] :为查询大小写信息.
  () :使用条件语句需要用圆括号。
  * :多位任意数。
  ^ :匹配模式头部分
  $ :匹配模式尾部分
  | :或
  ? :匹配可能出现的字符
  + :使用+匹配一个或多个字符
  条件操作符:
  > :小于
  例:[root@localhost awk]# awk '$3 < "48" {print $0}' data.f
  L.Tansleyaaa 05/99 4712  Brown-2 12 30 44544
  例:[root@localhost awk]# awk '{if($6 > $7) print $1 "\tok"}' data.f.bak
  J.Troll ok
  = :大于等于
  例:[root@localhost awk]# awk '$3 >= "48" {print $0}' data.f
  M.Tansley 05/99 48311 Green   8  40 44.44
  J.Lulu    06/99 48317 green   9  24 2678.
  P.Bunnyaaa   02/99 48    Yellow  12 35 2658
  J.Troll   07/99 4842  Brown-3 12 26 266666
  ~ :匹配正则表达式
  例:[root@localhost awk]# awk '{if ($4~/Brown/) print $0}' data.f
  J.Troll   07/99 4842  Brown-3 12 26 266666
  L.Tansleyaaa 05/99 4712  Brown-2 12 30 44544
  例:[root@localhost awk]# awk '$0 ~/Brown/' data.f
  J.Troll   07/99 4842  Brown-3 12 26 266666
  L.Tansleyaaa 05/99 4712  Brown-2 12 30 44544
  !~ :不匹配正则表达式
  例:[root@localhost awk]# awk '$0 !~/Brown/' data.f
  M.Tansley 05/99 48311 Green   8  40 44.44
  J.Lulu    06/99 48317 green   9  24 2678.
  P.Bunnyaaa   02/99 48    Yellow  12 35 2658
  例:[root@localhost awk]# awk '{if ($4 !~/Brown/) print $0}' data.f
  M.Tansley 05/99 48311 Green   8  40 44.44
  J.Lulu    06/99 48317 green   9  24 2678.
  P.Bunnyaaa   02/99 48    Yellow  12 35 2658
  任意字符匹配:
  例:[root@localhost awk]# awk '$0~/^...a/ ' data.f
  M.Tansley 05/99 48311 Green   8  40 44.44
  L.Tansleyaaa 05/99 4712  Brown-2 12 30 44544
  释:匹配开头前三位是任意字符第四位是a的字段。
  “或”的使用:
  例:[root@localhost awk]# awk '$0 ~ /(Brown|gree)/' data.f
  J.Lulu    06/99 48317 green   9  24 2678.
  J.Troll   07/99 4842  Brown-3 12 26 266666
  L.Tansleyaaa 05/99 4712  Brown-2 12 30 44544
  例;[root@localhost awk]# awk '$0 ~ /(Brown|[Gg]ree)/' data.f
  M.Tansley 05/99 48311 Green   8  40 44.44
  J.Lulu    06/99 48317 green   9  24 2678.
  J.Troll   07/99 4842  Brown-3 12 26 266666
  L.Tansleyaaa 05/99 4712  Brown-2 12 30 44544
  行首:
  例:[root@localhost awk]# awk '/^J/' data.f
  J.Lulu    06/99 48317 green   9  24 2678.
  J.Troll   07/99 4842  Brown-3 12 26 266666
  符合模式:
  && :两边的是都为真,才能打印信息。(只针对一行有效)
  例[root@localhost awk]# awk '{if ($3~/48/ && $4~/[Gg]reen/) print $0}' data.f
  M.Tansley 05/99 48311 Green   8  40 44.44
  J.Lulu    06/99 48317 green   9  24 2678.
  || :一边为真或全部为真
  例:[root@localhost awk]# awk '{if ($0~/Brown/ || $4~/[Gg]reen/) print $0}' data.f
  M.Tansley 05/99 48311 Green   8  40 44.44
  J.Lulu    06/99 48317 green   9  24 2678.
  J.Troll   07/99 4842  Brown-3 12 26 266666
  L.Tansleyaaa 05/99 4712  Brown-2 12 30 44544
  awk内置变量:
  NR:文件行数
  NF:域块个数
  FILENAME:所指定的文件名
  例:[root@localhost awk]# awk '{print NR,NF,$0} END{print FILENAME}' data.f
  1 7 M.Tansley 05/99 48311 Green   8  40 44.44
  2 7 J.Lulu    06/99 48317 green   9  24 2678.
  3 7 P.Bunnyaaa   02/99 48    Yellow  12 35 2658
  4 7 J.Troll   07/99 4842  Brown-3 12 26 266666
  5 7 L.Tansleyaaa 05/99 4712  Brown-2 12 30 44544
  data.f
  例:[root@localhost awk]# echo $PWD |awk -F"/" '{print $NF}'
  awk
  设置输入域到域变量名:
  例:[root@localhost awk]# awk '{name=$1;color=$4;if(color~/Ye/) print name "\tok"}' data.f
  P.Bunnyaaa      ok
  释:注意分号的使用,它分隔 awk命令。
  为变量赋值:
  例:[root@localhost awk]# awk '{if ($6 < "27") print $0}' data.f
  J.Lulu    06/99 48317 green   9  24 2678.
  J.Troll   07/99 4842  Brown-3 12 26 266666
  例:[root@localhost awk]#  awk 'BEGIN{shuzi="27 "} {if ($6 < shuzi) print $0}' data.f
  J.Lulu    06/99 48317 green   9  24 2678.
  J.Troll   07/99 4842  Brown-3 12 26 266666
  释:通常在BEGIN部分赋值是很有益的,可以在awk表达式进行改动时减少很多麻烦。
  修改数值域取值:
  例:[root@localhost awk]# awk '{if ($1=="M.Tansley") $6=$6-1;print $1,$6,$7}' data.f
  M.Tansley 39 44.44
  J.Lulu 24 2678.
  P.Bunnyaaa 35 2658
  J.Troll 26 266666
  L.Tansleyaaa 30 44544
  释:M.Tansley从原来的40下降到39。
  例:[root@localhost awk]# awk '{if ($1==$1) $6=$6-1;print $1,$6,$7}' data.f
  M.Tansley 39 44.44
  J.Lulu 23 2678.
  P.Bunnyaaa 34 2658
  J.Troll 25 266666
  L.Tansleyaaa 29 44544
  释:所有数字都减一。
  修改文本域:
  例:[root@localhost awk]# awk '{if ($1=="P.Bunnyaaa") ($1="P.Bunnyaaa.abcaaa");print $1}' data.f
  M.Tansley
  J.Lulu
  P.Bunnyaaa.abcaaa
  J.Troll
  L.Tansleyaaa
  释:记住字符串要使用双秒号( " ")不要忘记分号(;) ,并用圆括号括起整个语法。
  只显示修改记录:
  例:[root@localhost awk]# awk '{if ($1=="M.Tansley") {$1="M.Tansley.abc";print $1}}' data.f
  M.Tansley.abc
  例:[root@localhost awk]# awk '{if ($1=="M.Tansley") {$1="M.Tansley.abc";print $0}}' data.f
  M.Tansley.abc 05/99 48311 Green 8 40 44.44
  释:注意花括号的位置
  创建新的输出域:
  例:[root@localhost awk]# awk 'BEGIN{print "name\t fenzhi"} {if ($5 < $6) {$8=$6-$5;print $1,$8}}' data.f
  name     fenzhi
  M.Tansley 32
  J.Lulu 15
  P.Bunnyaaa 23
  J.Troll 14
  L.Tansleyaaa 18
  释:在输出结果前打印一个头,然后在比较数值,“$8=$6-$5”这是在为$8赋值。记住使用语法的格式。
  例:[root@localhost awk]# awk 'BEGIN{print "name \t shuzi"} {if ($5 < $6);diff=$6-$5;print $1,diff}' data.f
  name     shuzi
  M.Tansley 32
  J.Lulu 15
  P.Bunnyaaa 23
  J.Troll 14
  L.Tansleyaaa -90
  释:也可以使用域变量名。
  文件长度相加:
  例:[root@localhost awk]# ll -h |awk '/^[^d]/ {print $8"\t"$5} {tol+=$5} END{print "zongshu:" tol}'
  data.f  217
  data.f.bak      201
  zongshu:422
  释:数值相加的总和有偏差,应该是单位换算导致的结果有误。具体后期查一下。
  替换(gsub):
  例:[root@localhost awk]# awk 'gsub (/Green/,"abcd") {print $0}' data.f
  M.Tansley 05/99 48311 abcd   8  40 44.44
  释:整个记录中替换一个字符串为另一个,使用正则表达式格式, /目标模式/,替换模式
  awk简单脚本:
  例:[root@localhost awk]# cat jiaoben
  #!/bin/awk -f
  #
  BEGIN{
  print "hello"
  print "chengjiruxia"
  print "===================================="
  }
  (tot+=$6)
  END{print "zongshu:" tot
  print "pingjunshu" tot/NR}
  释:要给awk脚本加权限chmod u+x jiaoben ,不能这样使用sh jiaoben data.f。
  释:tot/NR是tot总数除以行数(NR)
  例:[root@localhost awk]# ./jiaoben data.f
  hello
  chengjiruxia
  ====================================
  M.Tansley 05/99 48311 Green   8  40 44.44
  J.Lulu    06/99 48317 green   9  24 2678.
  P.Bunnyaaa   02/99 48    Yellow  12 35 2658
  J.Troll   07/99 4842  Brown-3 12 26 266666
  L.Tansleyaaa 05/99 4712  Brown-2 120 30 44544
  zongshu:155
  pingjunshu31
  例:[root@localhost awk]# awk 'BEGIN{OFS=":"}{print $1,$3,$4}' digresult.txt
  news.sina.com.cn:111.12.251.212:111.12.251.203
  jupiter.sina.com.cn:111.12.251.217:111.12.251.212
  cmnetnews.sina.com.cn:111.12.251.219:111.12.251.217
  us.sina.com.cn:111.12.251.212:111.12.251.203
  www.sina.com:111.12.251.212:111.12.251.203
  释:将打印的结果已冒号分隔又叫输出分隔符


运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.iyunv.com/thread-557724-1-1.html 上篇帖子: 如何实现shell并发 下篇帖子: shell脚本三剑客之grep命令
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表