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

shell 正则表达三剑客--awk

[复制链接]

尚未签到

发表于 2018-8-27 08:00:37 | 显示全部楼层 |阅读模式
  awk命令
  awk和sed一样是流式编辑器,它也是针对文档中的行来操作的,一行一行的去执行。awk比sed更加强大,它能做到sed能做到的。awk工具其实是很复杂的,有专门的书籍来介绍它的使用。
  1 awk命令形式
  awk [-F|-f|-v] ‘BEGIN{} //{command1; command2} END{}’ file
  [-F|-f|-v]   大参数,-F指定分隔符,-f调用脚本,-v定义变量 var=value
  '  '         引用代码块
  BEGIN       初始化代码块,主要是引用全局变量,设置FS分隔符
  //           匹配代码块,可以是字符串或正则表达式
  {}           命令代码块,包含一条或多条命令
  ;          多条命令使用分号分隔
  END          结尾代码块,主要是进行最终计算或输出结尾摘要信息
  2 特殊变量符
  $0           表示整个当前行
  $1           每行第一个字段
  NF           字段数量变量
  NR           每行的记录号,多文件记录递增
  FNR          与NR类似,不过多文件记录不递增,每个文件都从1开始
  \t           制表符
  \n           换行符
  FS           BEGIN时定义分隔符
  RS           输入的记录分隔符, 默认为换行符(即文本是按一行一行输入)
  ~            匹配,与==相比不是精确比较
  !~           不匹配,不精确比较
  ==           等于,必须全部相等,精确比较
  !=           不等于,精确比较
  &&           逻辑与
  ||           逻辑或
  +            匹配时表示1个或1个以上
  /[0-9][0-9]+/    两个或两个以上数字
  /[0-9][0-9]*/    一个或一个以上数字
  FILENAME 文件名
  OFS          输出字段分隔符, 默认也是空格,可以改为制表符等
  ORS          输出的记录分隔符,默认为换行符,即处理结果也是一行一行输出到屏幕
  -F'[:#/]'      定义三个分隔符
  3 实例解析
  
  截取文档中的某个段
  [root@localhost ~]# head -n2 /etc/passwd |awk -F ':' '{print $1}'
  root
  bin
  解释一下,-F 选项的作用是指定分隔符,如果不加-F指定,则以空格或者tab为分隔符。 Print为打印的动作,用来打印出某个字段。$1为第一个字段,$2为第二个字段,依次类推,$0表示整行。
  [root@localhost ~]# head -n2 test.txt |awk -F':' '{print $0}'
  rto:x:0:0:/rto:/bin/bash
  operator:x:11:0:operator:/roto:/sbin/nologin
  注意awk的格式,-F后紧跟单引号,然后里面为分隔符,print的动作要用 { } 括起来,否则会报错。print还可以打印自定义的内容,但是自定义的内容要用双引号括起来。
  [root@localhost ~]# head -n2 test.txt |awk -F':' '{print $1"#"$2"#"$3"#"$4}'
  rto#x#0#0
  operator#x#11#0
  匹配字符或字符串
  [root@localhost ~]# awk '/oo/' test.txt
  operator:x:11:0:operator:/rooto:/sbin/nologin
  roooto:x:0:0:/rooooto:/bin/bash
  [root@localhost ~]# awk -F ':' '$1 ~/oo/' test.txt
  roooto:x:0:0:/rooooto:/bin/bash
  可以让某个段去匹配,这里的’~’就是匹配的意思
  [root@localhost ~]# awk -F ':' '/root/ {print $1,$3} /test/ {print $1,$3}' /etc/passwd
  root 0
  operator 11
  test 511
  test1 512
  awk还可以多次匹配,如上例中匹配完root,再匹配test,它还可以只打印所匹配的段。
  条件操作符
  [root@localhost ~]# awk -F ':' '$3=="0"' /etc/passwd
  root:x:0:0:root:/root:/bin/bash
  awk中是可以用逻辑符号判断的,比如 ‘==’ 就是等于,也可以理解为 ‘精确匹配’ 另外也有 >, ‘>=, ‘20' /etc/passwd
  postfix:x:89:89::/var/spool/postfix:/sbin/nologin
  abrt:x:173:173::/etc/abrt:/sbin/nologin
  sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
  tcpdump:x:72:72::/:/sbin/nologin
  user11:x:510:502:user11,user11's office,12345678,123456789:/home/user11:/sbin/nologin
  test:x:511:511::/home/test:/bin/bash
  test1:x:512:511::/home/test1:/bin/bash
  也可以配合段匹配一起使用:
  [root@localhost ~]# awk -F ':' 'NR>20 && $1 ~ /ssh/' /etc/passwd
  sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
  awk可以把段值更改
  [root@localhost ~]# head -n 3 /etc/passwd |awk -F ':' '$1="root"'
  root x 0 0 root /root /bin/bash
  root x 1 1 bin /bin /sbin/nologin
  root x 2 2 daemon /sbin /sbin/nologin
  awk还可以对各个段的值进行数学运算
  [root@localhost ~]# head -n2 /etc/passwd
  root:x:0:0:root:/root:/bin/bash
  bin:x:1:1:bin:/bin:/sbin/nologin
  [root@localhost ~]# head -n2 /etc/passwd |awk -F ':' '{$7=$3+$4}'
  [root@localhost ~]# head -n2 /etc/passwd |awk -F ':' '{$7=$3+$4; print $0}'
  root x 0 0 root /root 0
  bin x 1 1 bin /bin 2
  当然还可以计算某个段的总和
  [root@localhost ~]# awk -F ':' '{(tot=tot+$3)}; END {print tot}' /etc/passwd
  2891
  这里的END要注意一下,表示所有的行都已经执行
  [root@localhost ~]# awk -F ':' '{if ($1=="root") print $0}' /etc/passwd
  root:x:0:0:root:/root:/bin/bash
  日常应用
  应用1
  awk -F: '{print NF}' helloworld.sh          输出文件每行有多少字段
  awk -F: '{print $1,$2,$3,$4,$5}' helloworld.sh  输出前5个字段
  awk -F: '{print $1,$2,$3,$4,$5}' OFS='\t' helloworld.sh 输出前5个字段并使用制表符分隔输出
  awk -F: '{print NR,$1,$2,$3,$4,$5}' OFS='\t' helloworld.sh 制表符分隔前5个字段,并打印行号
  应用2
  awk -F'[:#]' '{print NF}'  helloworld.sh     指定多个分隔符: #,输出每行多少字段
  awk -F'[:#]' '{print $1,$2,$3,$4,$5,$6,$7}' OFS='\t' helloworld.sh  制表符分隔输出多字段
  应用3
  awk -F'[:#/]' '{print NF}' helloworld.sh      指定三个分隔符,并输出每行字段数
  awk -F'[:#/]' '{print $1,$2,$3,$4,$5,$6}' helloworld.sh  制表符分隔输出多字段
  应用4
  计算/home目录下,普通文件的大小,使用KB作为单位,int是取整的意思

  ls -l|awk 'BEGIN{sum=0} !/^d/{sum+=$5} END{print "total>
  ls -l|awk 'BEGIN{sum=0} !/^d/{sum+=$5} END{print "total>  统计netstat -anp 状态为LISTEN和CONNECT的连接数量分别是多少
  netstat -anp|awk '$6~/LISTEN|CONNECTED/{sum[$6]++} END{for (i in sum) printf "%-10s %-6s %-3s \n", i," ",sum}'
  应用6
  统计/home目录下不同用户的普通文件的总数是多少
  ls -l|awk 'NR!=1 && !/^d/{sum[$3]++} END{for (i in sum) printf "%-6s %-5s %-3s \n",i," ",sum}'
  mysql        199
  root         568
  统计/home目录下不同用户的普通文件的大小总size是多少
  ls -l|awk 'NR!=1 && !/^d/{sum[$3]+=$5} END{for (i in sum) printf "%-6s %-5s %-3s %-2s \n",i," ",sum/1024/1024,"MB"}'


运维网声明 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-557014-1-1.html 上篇帖子: shell 正则表达三剑客--sed 下篇帖子: SHELL-命令解释程序
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

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

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

扫描微信二维码查看详情

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


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


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


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



合作伙伴: 青云cloud

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