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

Shell脚本之awk篇

[复制链接]

尚未签到

发表于 2018-8-29 14:10:45 | 显示全部楼层 |阅读模式
  目录:
  一、概述
  二、awk基本语法格式
  三、awk基本操作
  四、awk条件及循环语句
  五、awk函数
  六、awk演示示例(源自于man手册)
  一、概述
  1. 产品概述:
  awk是一种编程语言,用于在linux/unix下对文本和数据进行扫描与处理。数据可以来自标准输入、文件、管道。
  awk分别代表其作者姓氏的第一个字母。因为它的作者是三个人,分别是Alfred Aho、Peter Weinberger、Brian Kernighan。
  实际上awk有很多种版本,如:awk、nawk、mawk、gawk、MKS awk、tawk...  这其中有开源产品也有商业产品。
  目前在Linux中常用的awk编译器版本有mawk,gawk,其中以RedHat为代表使用的是gawk,以Ubuntu为代表使用的是mawk。
  gawk是GNU Project 的awk解释器的开源代码实现。
  本文将以gawk作为讲解工具。
  2. 原理:
  1). awk逐行扫描文件,从第一行到最后一行,寻找匹配特定模式的行,并在这些行上进行你想要的操作。
  2). awk基本结构包括模式匹配(用于找到要处理的行)和处理过程(即处理动作)。
  pattern  {action}
# 提示:awk读取文件内容的每一行时,将对比改行是否与给定的模式相匹配,如果匹配则执行处理过程,否则对该行不做任何处理。  如果没有指定处理脚本,则把匹配的行显示到标准输出,即默认处理动作是print打印行;
  如果没有指定模式匹配,则默认匹配所有数据。
  3). awk有两个特殊的模式:BEGIN和END,他们被放置在没有读取任何数据之前以及在所有数据读取完成以后执行。
  3. awk流程图:
DSC0000.png

提示:awk将文件中的每一行当作一条记录,并将记录分割为若干字段,默认以空格或制表符为分隔符。  如This   is   a    test    file.    将分割为5个字段,awk可以对这5个字段进行分别处理。
  二、awk基本语法格式
  1. 格式:
  gawk [ POSIX or GNU style options ] -f program-file [ -- ] file ...
  注释:POSIX or GNU style options表示gawk支持POSIX以及GNU两种选项;-f后接脚本文件;file表示准备处理的文档名称。
  2. gawk支持以下选项:
  -F fs
  --field-separator fs
  指定以fs作为输入行的分隔符(默认分隔符为空格或制表符)
  -v var=val
  --assign var=val
  在执行处理过程以前,设置一个变量var值为val
  -f program-file
  --file program-file
  从脚本文件中读取AWK指令,以取代在命令参数中输入处理脚本
  -W compat
  -W traditional
  --compat
  --traditional
  使用兼容模式运行awk,GNU扩展选项将被忽略
  -W copyleft
  -W copyright
  --copyleft
  --copyright
  输出简短的GNU版权信息
  -W dump-variables[=file]
  --dump-variables[=file]
  打印全局变量(变量名、类型、值)到文件中,如果没有提供文件名,则自动输出至名为dump-variables的文件中。
  示例:[jacob@localhost ~]# awk  -W  dump-variables=out.txt  'x=1  {print x}'  test.txt
  -W exec file
  --exec file
  类似于-f选项,但脚本文件需要以#!开头;另外命令行的变量将不再生效
  -W help
  -W usage
  --help
  --usage
  显示各个选项的简短描述
  3. awk程序结构
  一个awk程序包含一系列的  模式 {动作指令} 或是函数定义。
  模式可以是:
  BEGIN
  END
  表达式
  表达式,表达式
  动作指令需要以{}引起来
  4. 简单示例:
  [jacob@localhost ~]# awk  '/^$/  {print  "Blank line}'   test.txt
  备注:/^$/通过正则表达式匹配空白行,动作为打印Blank line;即test.txt如有N个空白行,awk将在屏幕打印N个Blank line。
  [jacob@localhost ~]# awk  '/HOSTNAME/'  /etc/sysconfig/network
  备注:打印包含主机名的行,因为没有指定动作指令,默认动作为打印。
  [jacob@localhost ~]# cat  awk.sh
  '/^$/  {print  "Blank line}'
  [jacob@localhost ~]# awk  -f  awk.sh  test.txt
  备注:提前编辑一个awk脚本再通过-f选项调用该脚本。
  三、awk基本操作
  1. 记录与字段
  awk一次从文件中读取一条记录,并将记录存储在字段变量$0中。记录被分割为字段并存储在$1,$2 ..., $NF中(默认使用空格或制表符为分隔符)。
  内建变量NF为记录的字段个数
  示例:
  [jacob@localhost ~]# echo  hello the world |
  >awk  '{print  $1,$2,$3}'
  备注:读取输入行并输出第一个字段,第二个字段,第三个字段。
  [jacob@localhost ~]# echo  hello the world |
  >awk  '{print  $0}'
  备注:读取输入行并输出该行。
  [jacob@localhost ~]# echo  hello the world |
  >awk  '{print  NF}'
  备注:读取输入行并输出该行的字段个数:3个字段。
  [jacob@localhost ~]# echo  hello the world |
  >awk  '{print  $NF}'
  备注:读取输入行并输出该行的第三个字段,因为NF为3,所以$NF等同于取行的最后一个字段。
  2. 字段分隔符
  默认awk读取数据以空格或制表符作为分隔符,但可以通过-F或FS(field separator)变量来改变分隔符。
  示例:
  [jacob@localhost ~]# awk  -F:  '{print $1}'  /etc/passwd
  [jacob@localhost ~]# awk  'BEGIN {FS = ":"} {print $1}'  /etc/passwd
  备注:以上两个示例均将字段的分隔符改冒号(:),即以冒号为分隔符打印passwd文件的第一个字段(帐号名称)。
  注意:如果使用FS改变分隔符的话,需要在BEGIN处定义FS,因为在读取第一行前就需要改变字段分隔符。
  进阶:指定多个字段分隔符(文档内容为:hello the:word,!)
  [jacob@localhost ~]# echo  'hello the:word,!' |
  >awk  'BEGIN {FS="[:, ]"}  {print $1,$2,$3,$4}'
  3. 内置变量
  以下为awk内置变量:
  ARGC        命令行参数个数
  FILENAME    当前输入文档的名称
  FNR        当前输入文档的当前记录编号,尤其当有多个输入文档时有用
  NR        输入流的当前记录编号
  NF        当前记录的字段个数
  FS        字段分隔符
  OFS        输出字段分隔符,默认为空格
  ORS        输出记录分隔符,默认为换行符\n
  RS        输入记录分隔符,默认为换行符\n
  示例:
  [jacob@localhost ~]# cat  test1.txt
This is a test file. Welcome to Jacob's Class.  [jacob@localhost ~]#cat   test2.txt
Hello the world. Wow! I'm overwhelmed. Ask for more.  [jacob@localhost ~]# awk  '{print FNR}'  test1.txt  test2.txt
1 2 1 2 3  备注:输出当前文档的当前行编号,第一个文件两行,第二个文件三行。
  [jacob@localhost ~]# awk  '{print NR}'  test1.txt  test2.txt
1 2 3 4 5  备注:awk将两个文档作为一个整体的输入流,通过NR输入当前行编号。
  [jacob@localhost ~]# awk  '{print NF}'  test1.txt
5 4  备注:test1.txt文档的第一行有5个字段,第二行有4个字段。
  [jacob@localhost ~]# awk  'BEGIN {FS = ":"} {print $1}'  /etc/passwd
  [jacob@localhost ~]# awk  '{print $1,$2,$3}'  test1.txt
  备注:默认print输出时,各参数将的输出分隔符默认为空格,所以输出内容如下
  This is a
  Welcome to Jacob's
  [jacob@localhost ~]# awk  'BEGIN {OFS="-"} {print $1,$2,$3}'  test1.txt
备注:通过OFS将输出分隔符设置为"-",这个print在输出第一、二、三个字段时,中间的分隔符为"-",结果如下This-is-a Welcome-to-Jacob's  [jacob@localhost ~]# cat  test3.txt
mail from: tomcat@gmail.com subject:hello data:2012-07-12 17:00 content:Hello, The world.  mail from: jerry@gmail.com subject:congregation data:2012-07-12 08:31 content:Congregation to you.  mail from: jacob@gmail.com subject:Test data:2012-07-12 10:20 content:This is a test mail.  [jacob@localhost ~]# awk 'BEGIN {FS="\n"; RS=""} {print $3}'  test3.txt
  备注:读取输入数据,以空白行为记录分隔符,即第一个空白行前的内容为第一个记录,第一个记录中字段分隔符为换行符。
  以上awk的效果为打印所有的邮件时间,即每个记录的第三个字段。
  4. 表达式与操作符
  表达式是由变量、常量、函数、正则表达式、操作符组成,awk中变量有字符变量和数字变量。如果在awk中定义的变量没有初始化,则初始值为空字串或0。
  注意:字符操作时一定记得需要加引号
  1) 变量定义示例:
  a="welcome to beijing"
  b=12
  2) 操作符(awk操作符与C语言类似)
  +        加
  -        减
  *        乘
  /        除
  %        取余
  ^        幂运算
  ++        自加1
  --        自减1
  +=        相加后赋值给变量(x+=9等同于x=x+9)
  -=        相减后赋值给变量(x-=9等同于x=x-9)
  *=        相乘后赋值给变量(x*=9等同于x=x*9)
  /=        相除后赋值给变量(x/=9等同于x=x/9)
  >        大于
  <        小于
  >=        大于等于
  

运维网声明 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-558262-1-1.html 上篇帖子: shell批量增加账户 下篇帖子: shell学习1--初识
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

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

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

扫描微信二维码查看详情

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


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


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


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



合作伙伴: 青云cloud

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