AWK说明-及语法格式。

来源:互联网 发布:手机淘宝开店在哪里 编辑:程序博客网 时间:2024/05/17 03:28

AWK简介

  • awk是一款文本信息的统计,报告生成的工具.awk有自己的语法,是一款独立的编程语言.
  • awk支持从文本文件中读取内容,或者从标准的输入中读取内容.
  • awk 的最终起源于行编辑器ed,awk继承了行编辑器的特点,循环的读取文本的每一行(或者是分隔符分割的每一段文本)直至文本结束,但是awk加入了段分割符的概念.将每次读入的行进行再次分割.awk每次读取的行都只是未经过awk语句处理的对象。或读取行后会根据段分割符在将行分成多个对象。结构近似数组,然后进行指定语句的操作
  • awk 的对命令的处理可以称为命令的解释,或脚本语言的解释。 awk的语句书写格式,属于模块化风格,特别是if,else语句表现的特别明显有点类似于bash中的匿名函数。每个语句块必须使用{}进行约束

awk的基本执行过程:

  • 执行BEGIN语句块中的内容,语句为可选语句.多用于执行变量的初始化,报表的头输出.
  • 从标准输入或文件中读取行分割符(-F定义的字符)分割的行进入内存,进行语句之前的条件匹配,在没有条件时默认为符合执行条件.符合条件执行,不符合条件则尝试匹配下一个语句之前的条件.直至所有条件匹配全部完成.当语句为空时默认执行{print $0}
  • 继续读取下一行,直至末尾
  • 执行END定义的语句内容,同样也为可选语句.多用于报表的统计信息输出.

基本格式 :

awk 选项 条件 语句 文件

  • 在bash命令行中执行awk时,在向awk传入语句时,语句优先由bash优先解释。也就是说可以向awk传入语句时可以,bash展开传入一些奇怪的东西,比如说系统变量,比如说{1..4}


  • 选项:

-f 从文件中读取处理命令
-F 指明行的段分隔符;分割针对输入时的数据。支持模式匹配。扩展的正则表达式,目的是将行分割成为多个对象.或确定每次循环时待处理的对象(最小待处理单位)是什么.默认的
-v 自定义变量
awk -v



  • 条件:

awk是一门语言,请以编程的视角去看待条件。
条件为执行条件后的语句的要求。符合条件才可执行语句,条件即为对语句的判断,可以使用正则匹配,基于正则的模式定界,字符串比较,可以使用算数条件表达式,也可以是BEGIN,END特殊条件。
算数条件表达式,最终返回运算结果,当运算结果为0时,语句不执行。
在进行条件验证时行已经被分割成最小的单位,并已经对最小单位的小数量,内容,行号等信息进行了统计。

  • 当条件为空时执行每一行
例:正则_匹配正则匹配的每一行      awk '/^UUID/{print $1}' /etc/fstab   #匹配以UUID为开始的行,并执行{}中的语句。print $1       awk '!/^UUID/{print $1}' /etc/fstab  #匹配以非UUID为开始的行,执行{}中的语句 。print $1例:算数计算_条件为真该行才会被处理 ,条件 为假则不处理 。    awp -F: '$3>=1000{print $1,$3}' /etc/passwd    awp -F: '!$3>=1000{print $1,$3}' /etc/passwd    awk -F: '(NR>=2&&NR<=10){print $1}'例:字符串比较_比较结果为真进入循环    awk -F'$NF="/bin/bash"{print $1,$NF}' /bin/passwd    awk -F'$NF~/bash$/{print $1,$NF}' /bin/passwd    awk -F: '! ($NF=="/bin/bash")' /etc/passwd例:行范围_范围内的行做处理 ,好像只支持模式定界    awk -F'10,20{print $1}'  #----失败了      awk -F'/^root/,/^myuser/{print $1}'例:特殊条件_BEGIN/END     awk 'BEGIN{print "  username    ID  \n------------"}{printf "%10s:%-s" $1,$3}END{print "=========\n"}'        # BEGIN:在开始之前显示一次          # END:在文本处理完成 ,命令未完成时,执行一次例:特殊条件_0,空    awk -v aa="" 'aa' /etc/passwd     #变量aa的值为空 ,(语句为空执行默认语句)。但是条件为空,不执行默认语句。    awk -v aa=" " 'aa' /etc/passwd    #变量aa的值为‘ ’空格不为空执行默认语句    awk -v aa="0" 'aa' /etc/passwd    #变量aa的值为0,条件为最终值为0,默认语句不执行。    awk -v aa="1" 'aa' /etc/passwd    #变量aa的值为1 ,条件返回值为1,默认语句执行。    awk -v aa=0 'aa++' /etc/passwd    #aa初始值为0,第一条语句条件为a++,首先返回a的值在进行自加运算。所以打印第一行外所有行。    echo "123"| awk -v a=1 'a=0{print $1}' #a的初始值为1.第一条语句条件为a=0,对a进行了重新赋值。此时返回a赋值后的值,条件为0,语句不执行。


  • 语句:

符合条件执行的动作,awk是一门语言,所以以编程的思维去思考。只是awk的变量大多数是awk自动赋值的。并在内部根据自己的规则自动变化(比如行计数器NR,又比如$1等)
当{}中存在多条语句时使用;进行分隔。

 当语句为空时,默认执行{print $0}awk '!0' /etc/passwd

print :

打印 打印的类型需要进行设定 “” 定义字符串 数值直接为数值$为最小元素引用变量直接引用 在不指定打印内容时,打印整个行(我就这么一写)#在没有指定条件,以及没有指定print输出的内容时,默认输出整行例:  >>echo "hello" |awk '{print}'      hello#在指定了多个输出内容时,对象的格式不同,使用的定义也不同例:         echo "hello word" |awk  '{print $1"\t"$2}'    hello   word    echo "hello word" |awk  -F' ' '{print $1"---"$2}'    hello---word    echo "hello word" |awk  -F' ' '{nu=10;print $1"---"$2"---"nu}'    hello---word---10#在没有使用,分割字段时,默认字段是连续的,定义了输出的字段,分割的是每个输出的字段例:    echo "hello word" |awk  -F' ' '{print $1$2}'    helloword    echo "hello:word:haha:asd" |awk  -v FS=':' -v OFS='---' '{print $1$2}'    helloword    echo "hello:word:haha:asd" |awk  -v FS=':' -v OFS='---' '{print $1,$2}'    hello---word    echo "hello:word:haha:asd" |awk  -v FS=':' -v OFS='---' '{print $1,$2,$1$2}'    hello---word---helloword

printf

格式化输出字符串格式符:    %c ascii        echo "asd"| awk '{printf "%c\n",$1}'    %d i 十进制  整数          echo "123"| awk '{printf "%-d\n",$1}'    %e %E 科学记数法     %f 显示 浮点数      %s 显示 字符串          echo "123"| awk '{printf "%s\n",$1}'        123        echo "123"| awk '{printf "%s\n","asd"}'        asd    %% 显示%自身    %g %G 以科学技术法显示     %u 无符号的 整数 修饰符 :    # 显示宽度      #。#;第二个  # 表示 小数点  后的精度     - : 左对齐,默认右对齐。    + :显示数字的正负符号

条件表达式:

格式:条件?条件为真的语句:条件为假的语句 awk ‘{$3>=1000?usertype="......":usertype="::::::";printf "%15s:%-s\n",$1,usertype}’

控制语句:

if:格式:    if(条件){语句}    if(条件){语句} else {语句}例:    awk -F: '{if($3>1000) print $1,$3}' /etc/passwd  #打印非系统用户    awk -F: '{if($3>1000){printf "普通用户:%s",$1} else {printf "系统用户:%s",$1}}' #对系统的用户进行判断,输出结果。    df -h |awk -F% '/\/dev\/sd/{print $1}'|awk '{if($NF>=16)print $1}'    df -h |awk -F% '/\/dev\/sd/{print $1}'|awk '$NF>=16{print $1}'

循环语句:

whilewhile (条件) {语句}        条件为真进入循环 ,条件为假退出循环。    awk '/^[[:space:]]*linux/{i=1;while(i<NF){print $i,length($i);i++}}' /etc/grub2.cfg    awk '/^[[:space:]]*linux/{i=1;while(i<NF){if(length($i)>7){print $i,length($i)};i++}}' /etc/grub2.cfg    awk '/^[[:space:]]*linux16/{i=1;while(i<=NF) {if(length($i)>=10){print $i,length($i)}; i++}}' /etc/grub2.cfg
dodo{语句} while(条件)        首先执行do后面的语句。然后对while中的条件进行判断。条件符合继续执行do后的语句。        awk 'BEGIN{total=0;i=0;do{total+=i;i++;}while(i<=100);print total}'        awk 'BEGIN{total=0;i=0;while(i<=100){total+=i;i++};print total}'
forfor (i=1;i<10;i++){语句}            awk /[[:space:]]*linux/{for(i=1;i<=NF;i++){print $i,length($i)}} /etc/grub2.cfg        for可以实现遍历数组元素 :            格式 :for (i in 数组名称)遍历时 i被赋值的是每个索引,
switch
循环跳转break        跳出当前循环,break # :跳出#层循环contiune        结束本次次循环, continue # :结束啊 #层的本次循环。next :结束 当前行的处理,读取下一行。gawk 的自带循环 ,结束行的处理,进入下一行         awk -F: '{if($3%2!=0) next;print $0 }' /etc/passwd        打印奇数行deleteexit

函数:

内置函数    lrngth        统计指定字符串的长度,并返回。        例:  echo "asdd"|awk '{print length($1)}' #统计字符串出现的次数。randsrand        rand,与srand 组合使用返回一个随机数        例: awk 'BEGIN{srand();for(i=1;i<=10;i++){print int(rand()*100)}}'sub        格式sub(r,s,[t])        处理字符串t(可以是单纯的字符串,变量,位置引用),对t进行模式匹配,模式定义在r中,将模式r所匹配的内容替换成s中的内容,但是只进行1次替换        例: echo "2008:08:08:08 08:08:08:08" |awk 'sub(/:/,"-",$0)'gsub        格式 gsub (r,s,[t])        处理字符串t(可以是单纯的字符串,变量,位置引用),对t进行模式匹配,模式定义在r中,将模式r所匹配的内容替换成s中的内容,对于待处理的字符串t进行全局替换。        例: echo "Yd$C@M05MB%9&Bdh7dq+YVixp3vpw"|awk '{gsub(/[^0-9]/,"",$0);print $0}'        echo "Yd$C@M05MB%9&Bdh7dq+YVixp3vpw"|awk 'gsub(/[^0-9]/,"",$0)'split        格式 split(a,array,[r])        以r为分隔符,分割字符串a,并将分割后的字符串分别存入数组,数组的下标从1开始,第一个索引为1,第二个索引为2.        netstat -tan |awk '/^tcp/{split($4,ip,":");a[ip[1]]++}END{for(i in a){print i,a[ip[1]]}}'int        格式 int(需要转换的小数,或字符串)        将指定的内容转换为整数类型。system        格式: system("系统命令")        将传入的字符串以系统命令方式执行。命令先经过bash解释传入,所有传入时到awk解释时,必须保证是需求的字符,在经过awk解释时,必须符合awk的语法。也就是保证经bash解释后成为符合awk语法格式切符合需求的字符。或者确保传入的函数的值,为需要的值。        例:awk 'BEGIN{system("hostname")}'           awk 'system("hostname"){i=0}'
自定义函数    格式:    function 函数名称 (参数1 ,参数2 。。。){    语句1     语句2    return 数值        }将语句与函数定义在文件中,使用awk运行。    #cat fun.awk        function max(v1,v2) {        v1>v2?var=v1:var=v2        return var        }        BEGIN{a=3;b=2;print max(a,b)}    #awk –f fun.awk将语句与函数定义在脚本中,使用shebang,直接运行脚本。将awk程序写成脚本,直接调用或执行    #cat f1.awk        {if($3>=1000)print $1,$3}    #awk -F: -f f1.awk /etc/passwd    #cat f2.awk        #!/bin/awk –f        #this is a awk script        {if($3>=1000)print $1,$3}        #chmod +x f2.awk    #f2.awk –F: /etc/passwd
awk脚本中传递参数:格式:awkfile var=value var2=value2... Inputfile注意:在BEGIN过程中不可用。直到首行输入完成以后,变量才可用。可以通过-v 参数,让awk在执行BEGIN之前得到变量的值。命令行中每一个指定的变量都需要一个-v参数#cat test.awk    #!/bin/awk –f    {if($3 >=min && $3<=max)print $1,$3}#chmod +x test.awk#test.awk -F: min=100 max=200 /etc/passwd

数据引用:

行的分段引用每个分段之间使用,进行分割,当不使用,进行分割时默认为一个字段,$1 :该行的第一个元素$2 :该行的第一个元素换行符有必要写一下,换个行而已没什么神圣的,解释了是换行不解释就是\n,awk,看到的文本是连续的,或者说是一串,只是到了换行被截断。

变量:

内建的变量。    内建变量的赋值 -v FS=" " 每一个-v用来定义一个变量,    FS:输入的字段分割符,默认为空白字符    OFS:输出的字段分隔符,默认也为空白字符。    RS:输入时指明的行分割符,默认就是换行符,    ORS:输出时的行分隔符,默认为换行符    NF :行中的字段数量     NR :行计数器 ,如果跟了多个 文件  ,编号会连续     FNR : 基于文件的 行计数器 。    FILENAME : 当前的文件名    ARGC :命令行中的参数个数     ARGV :命令行中的参数 ,ARGV为数组,参数为命令自身及后跟随的文件 ,语句不计入参数 自定义的变量    -v var=value    在 与语句中 直接 定义      多条与语句之间 使用  ;分隔 

操作符

算数操作符 :双目运算符  :x+y x-y x*y x/y x^y x%y单目运算符 :-x :将x 转化为负数 +x :将字符串x 转化为 数值 字符串的 操作符 :连接符什么  鬼 赋值操作符 :+ += -= *= /= ^= %=++  --> >= < <= != ==

模式匹配:

~ : 是否匹配 !~: 是否  不匹配  逻辑操作符 : &&  || ! 函数调用 : 函数名(参数 ,参数 )

数组:

awk的数组为关联数组,就是Python中的字典。数组索引可以使用任意的字符串索引,字符串使用引号 如果某数组元素不存在,引用时会创建初始值为none,在进行数学运算时 none会自动转化为0进行计算。数组赋值array[\$1]=aaarray[\$1]++ awk '!arr[\$0]++' /etc/fstab    排除重复的行,取出第一行是对应的数组的内容为空,将none返回然后进行自加后值为1,返回的值经过!取反为真执行默认语句,同样的语句第二次出现时,返回的值为1,经过!取反,值为假,反而不执行. awk '{arr[$0]++;print $0,arr[$0]}'    打印并统计重复行出现的次数.遍历数组netstat -tan | awk '/tcp\>/{stat{$NF}++}END{for(i in stat){print i,stat[i]}}

原创粉丝点击