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

[经验分享] Linux命令:awk简介

[复制链接]

尚未签到

发表于 2018-5-22 07:15:59 | 显示全部楼层 |阅读模式
  awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大。简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理。
  备注:awk有3个不同版本: awk、nawk和gawk,未作特别说明,一般指gawk,gawk 是 AWK 的 GNU 版本。
  

  语法:
  awk [options] 'program' file file ...
  awk [options] 'PATTERN{action}' file file ...
  -F CHAR:指定分隔符
  awk的输出:
  print item1, item2,...
  

  要点:
  (1) 各项目之间使用逗号分隔,而输出时则使用输出分隔符分隔
  [root@localhost ~]# awk -F ":" '/^root/ {print $1,$7}' /etc/passwd
  root /bin/bash
  

  (2) 输出的各item可以是字符串或数值、当前记录的字段、变量或awk的表达式;数值会被隐式转换为字符串后输出
  [root@localhost ~]# cat /etc/passwd |awk -F ':' 'BEGIN {print "name shell"} {print $1,$7}'
  name shell
  root /bin/bash
  bin /sbin/nologin
  daemon /sbin/nologin
  adm /sbin/nologin
  lp /sbin/nologin
  

  (3) print后面item如果省略,相当于print $0;输出空白,使用pirnt ""
  [root@localhost ~]# awk -F ":" '/^root/ {print}' /etc/passwd
  root:x:0:0:root:/root:/bin/bash
  [root@localhost ~]# awk -F ":" '/^root/ {print $0}' /etc/passwd
  root:x:0:0:root:/root:/bin/bash
  [root@localhost ~]# awk -F ":" '/^root/ {print ""}' /etc/passwd
  

  awk的变量:
  内置变量,自定义变量
  (1) 内置变量:
  FS:Field Seperator, 输入时的字段分隔符(相当于-F:)
  RS:Record Seperator, 输入行分隔符
  OFS: Output Field Seperator, 输出时的字段分隔符
  ORS: Outpput Row Seperator, 输出时的行分隔符
  NF:Numbers of Field,字段数
  NR:Numbers of Record, 行数;所有文件的一并计数
  FNR:行数;各文件分别计数
  ARGV:数组,保存命令本身这个字符,awk '{print $0}' 1.txt 2.txt,意味着ARGV[0]保存awk,
  ARGC: 保存awk命令中参数的个数
  FILENAME: awk正在处理的当前文件的名称
  示例:
  使用FS指定分隔符
  [root@localhost ~]# awk 'BEGIN{FS=":"} {print $1,$7}' /etc/passwd
  root /bin/bash
  bin /sbin/nologin
  daemon /sbin/nologin
  adm /sbin/nologin
  lp /sbin/nologin
  sync /bin/sync
  

  统计/etc/passwd:文件名,每行的行号,每行的列数,对应的完整行内容
  [root@localhost ~]# awk -F ":" '{print "filename:"FILENAME",linenumber:"NR",columns:"NF",linecontent:" $0 }' /etc/passwd
  filename:/etc/passwd,linenumber:1,columns:7,linecontent:root:x:0:0:root:/root:/bin/bash
  filename:/etc/passwd,linenumber:2,columns:7,linecontent:bin:x:1:1:bin:/bin:/sbin/nologin
  

  自定义变量
  -v var_name=VALUE
  变量名区分字符大小写
  (1) 可以program中定义变量
  (2) 可以命令行中通过-v选项自定义变量
  

  示例:统计/etc/passwd的账户人数
  [root@localhost ~]# awk -F: '{count++;print $0} END{print "user count is", count}' /etc/passwd
  root:x:0:0:root:/root:/bin/bash
  bin:x:1:1:bin:/bin:/sbin/nologin
  daemon:x:2:2:daemon:/sbin:/sbin/nologin
  adm:x:3:4:adm:/var/adm:/sbin/nologin
  lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
  user count is 5
  

  printf命令
  命令的使用格式:printf format, item1, item2,...
  要点:
  (1) 要指定format;
  (2) 不会自动换行;如需换行则需要给出\n
  (3) format用于为后面的每个item指定其输出格式;
  

  format格式的指示符都%开头,后跟一个字符:
  %c: 显示字符的ASCII码;
  %d, %i: 十进制整数;
  %e, %E: 科学计数法显示数值;
  %f: 显示浮点数;
  %g, %G: 以科学计数法格式或浮点数格式显示数值;
  %s: 显示字符串;
  %u: 显示无符号整数;
  %%: 显示%自身;
  

  修饰符:
  #:显示宽度
  -:左对齐
  +:显示数值的符号
  .#: 取值精度
  

  示例:显示用户的UID
  [root@localhost ~]# awk -F: '{printf "UID: %d\n",$3}' /etc/passwd
  UID: 0
  UID: 1
  UID: 2
  UID: 3
  UID: 4
  UID: 5
  UID: 6
  UID: 7
  UID: 8
  

  统计/etc/passwd:文件名,每行的行号,每行的列数,对应的完整行内容
  [root@localhost ~]# awk -F ':' '{printf("filename:%10s,linenumber:%s,columns:%s,linecontent:%s\n",FILENAME,NR,NF,$0)}' /etc/passwd
  filename:/etc/passwd,linenumber:1,columns:7,linecontent:root:x:0:0:root:/root:/bin/bash
  filename:/etc/passwd,linenumber:2,columns:7,linecontent:bin:x:1:1:bin:/bin:/sbin/nologin
  

  awk的操作符
  算术操作符:
  x+y
  x-y
  x*y
  x/y
  x**y, x^y
  x%y
  -x:负值
  +x:转换为数值
  

  字符串操作符:连接
  

  赋值操作符:
  =
  +=
  -=
  *=
  /=
  %=
  ^=
  **=
  ++
  --
  如果模式自身是=号,要写为/=/
  

  比较操作符:
  <
  <=
  >
  >=
  ==
  !=
  ~:模式匹配,左边的字符串能够被右边的模式所匹配为真,否则为假;
  !~:
  逻辑操作符:
  &&: 与
  ||:或
  

  条件表达式:
  selector?if-true-expression:if-false-expression
  示例:查看用户的UID大于500显示为普通用户,否则显示为管理员或系统用户

  [root@localhost ~]# awk -F: '{$3>500?utype="Common User":utype="Admin or Syetem user";print $1, "is", utype}' /etc/passwd
  root is Admin or Syetem user
  bin is Admin or Syetem user
  daemon is Admin or Syetem user
  adm is Admin or Syetem user
  user9 is Common User
  user10 is Common User
  

  模式:
  (1) Regexp: 格式为/PATTERN/
  仅处理被/PATTERN/匹配到的行
  (2) Expression: 表达式,其结果为非0或非空字符串时满足条件
  仅处理满足条件的行
  (3) Ranges: 行范围,此前地址定界
  NR 仅处理范围内的行
  (4) BEGIN/END: 特殊模式,仅在awk命令的program运行之前(BEGIN)或运行之后(END)执行一次
  (5) Empty:空模式,匹配任意行
  

  示例:显示用户名以及Shell类型
  [root@localhost ~]# awk -F: '$NF~/bash$/{print $1,$NF}' /etc/passwd
  root /bin/bash
  mk /bin/bash
  bash /bin/bash
  testbash /bin/bash
  basher /bin/bash
  

  显示指定范围内的用户名以及Shell类型
  [root@localhost ~]# awk -F: 'NR>=1&&NR<=5{print $1,$NF}' /etc/passwd
  root /bin/bash
  bin /sbin/nologin
  daemon /sbin/nologin
  adm /sbin/nologin
  lp /sbin/nologin
  

  统计某个文件夹下的文件占用的字节数
  [root@localhost ~]# ll /etc/ |awk 'BEGIN {size=0} {size=size+$5} END{print "[end]size is ",size}'
  [end]size is 1995496
  

  统计某个文件夹下的文件占用的字节数,以M为单位显示
  [root@localhost ~]# ll /etc/ |awk 'BEGIN {size=0} {size=size+$5} END{print "[end]size is ",size/1024/1024,"M"}'
  [end]size is 1.90305 M
  

  常用的action:
  (1) Expressions
  (2) Control statements
  (3) Compound statements
  (4) input statements
  (5) output statements
  

  控制语句:
  if-else
  格式:if (condition) {then body} else {else body}
  判断用户UID大小并显示用户的类型
  [root@localhost ~]# awk -F: '{if ($3>=500) {print $1 "is a Common User"} else {print $1 "is a Admin or System User"}}' /etc/passwd
  rootis a Admin or System User
  binis a Admin or System User
  user9is a Common User
  user10is a Common User
  

  判断用户UID与GID是否相同
  [root@localhost ~]# awk -F: '{if ($3=$4) {print $1 "is a good guy"} else {print $1 "is a bad guy"}}' /etc/passwd
  rootis a bad guy
  binis a good guy
  daemonis a good guy
  admis a good guy
  lpis a good guy
  syncis a bad guy
  

  while
  格式:while (condition) {while body}
  显示文件的奇数行
  [root@localhost ~]# awk '{i=1;while (i<=NF){printf "%s",$i;i+=2};print""}' /etc/inittab
  #isusedupstarttherunlevel.
  #
  #OTHERHEREHAVEEFFECTYOUR
  #
  #initializationstarted/etc/init/rcS.conf
  

  do-while循环
  格式:do {do-while body} while (condition)
  for循环
  格式:for (variable assignment; condition; iteration process) {for body}
  

  示例:查看访问web服务器的每个IP的访问次数
  [root@localhost ~]# ab -n 10000 -c 100 http://192.168.111.128/index.html(网站访问压力测试)
  This is ApacheBench, Version 2.3 <$Revision: 655654 $>
  Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
  Licensed to The Apache Software Foundation, http://www.apache.org/
  Benchmarking 192.168.111.128 (be patient)
  Completed 1000 requests
  Completed 2000 requests
  [root@localhost ~]# awk '{ip[$1]++}END{for (i in ip) {print i,ip} }' /var/log/httpd/access_log
  192.168.111.128 30031
  

  next
  提前结束对本行的处理进而提前进入下一行的处理;
  

  示例:打印奇数用户
  [root@localhost ~]# awk -F: '{if($3%2==0) next;print $1,$3}' /etc/passwd
  bin 1
  adm 3
  sync 5
  [root@localhost ~]# awk -F: '{if(NR%2==0) next;print NR,$1}' /etc/passwd
  1 root
  3 daemon
  5 lp
  

  数组
  传统数组:Index编号从1开始;
  关联数组:
  array[index-expression]
  index-expression: 可以使用任意字符串; 如果某数组元素事先不存在,那么在引用时,awk会自动创建此元素并将其初始化为空串;因此,要判断某数组是否存在某元素,必须使用“index in array”这种格式;
  A[first]="hello awk"
  print A[second]
  要遍历数组中的每一个元素,需要使用如下特殊结构:
  for (var in array) {for body}
  其var会遍历array的索引;
  state[LISTEN]++
  state[ESTABLISHED]++
  

  示例:显示LISTEN 或ESTABLISHED等链接状态的次数
  [root@localhost ~]# netstat -tan | awk '/^tcp/{++state[$NF]}END{for (s in state) {print s,state}}'
  ESTABLISHED 1
  LISTEN 11
  

  示例:查看访问web服务器的每个IP的访问次数
  [root@localhost ~]# ab -n 10000 -c 100 http://192.168.111.128/index.html(网站压力测试)
  This is ApacheBench, Version 2.3 <$Revision: 655654 $>
  Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
  Licensed to The Apache Software Foundation, http://www.apache.org/
  Benchmarking 192.168.111.128 (be patient)
  Completed 1000 requests
  Completed 2000 requests
  [root@localhost ~]# awk '{ip[$1]++}END{for (i in ip) {print i,ip} }' /var/log/httpd/access_log
  192.168.111.128 30031
  

  删除数组元素:
  delete array[index]
  

  awk的内置函数
  split(string,array[,fieldsep[,seps]]):
  功能:将string表示的字符串以fieldsep为分隔符进行切片,并切片后的结果保存至array为名的数组中;数组下标从1开始;
  root:x:0:0::/root:/bin/bash
  user[1]="root", user[2]
  
  此函数有返回值,返回值为切片后的元素的个数
  [root@localhost ~]# netstat -tn | awk '/^tcp/{lens=split($5,client,":");ip[client[1]]++}END{for (i in ip) print i,ip}'
  192.168.111.1 1
  

  length(string)
  功能:返回给定字串的长度
  substr(string,start[,length])
  功能:从string中取子串,从start为起始位置为取length长度的子串;

运维网声明 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.yunweiku.com/thread-478862-1-1.html 上篇帖子: linux之route命令 下篇帖子: Linux 学习:Linux特殊权限习题
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

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

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

扫描微信二维码查看详情

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


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


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


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



合作伙伴: 青云cloud

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