文本处理工具三剑客之awk

文本处理工具:grep,sed,awk

awk:报告生成器,格式化文本输出

AWK: Aho ,Weinberger,Kernighan

gawk:GNU awk

gawk – pattren  scanning  and  processing  language

基本语法:gawk  [options ] ‘program’ FILE….

    program:PATTERN{ACTION STATEMENTS}

        语句之间用分号分隔

选项:

    -F:指明输入时用到的字段分隔符

    -v:var=value:自定义变量

        blob.png

  1. print

print item1,item2,…..

要点:

    1.以逗号作为分隔符

    2.输出的各item可以是字符串,也可以是数字。也可以是当前记录的字段,变量或者awk的表达式

    3.如果省略item,相当于print $0

实例:

 注意print里面的字符要用引号 引起来  

        blob.png

如果是变量就不要用引号了

        blob.png

省略item相当于print $0,而print “”相当于空,而print “ ”表现是空格

        blob.png

2.变量

    a,内建变量(分隔符)

        FS:inuput field seperator,默认为空白字符  

          OFS: output field seperator,默认为空白字符

          RS:inuput record seperator,输入的换行符

          ORS:output record seperator,输出的换行符

        blob.png

            blob.png

因为此处只定义了输入时换行符为“”,并没有定义输出换行符,所有默认,在输出的时候空格时要换行

,原默认要换行的时候也会换行

           blob.png

        

        NF:number of field,字段数量

               {print  NF} 显示字段数 {print 1}

               ,{print  $NF}显示最后一个字段,类似于{print $1}

          blob.png

          NR: number of field,行数 (如果两个文件一起显示,会直接连在一起,不会分开计数)

                {print  NR} 显示行数

          blob.png 

          FNR:file number of field, 各文件分开计数行数

           blob.png   

          FILENAME:当前文件名

          blob.png

          ARGC:命令行参数的个数

          ARGV:数组,保存的是命令行所给定的各参数

          blob.png

    b.自定义变量

        1.-v var=value

            变量名区分大小写

        blob.png

        2.在program中直接定义

        blob.png

3.printf命令

    格式化输出:printf FORMAT ,item1,item2,….

        1.FORMAT是必须要给出的

        2.不会自动换行,需要显示给出换行控制符,\n

        3.FORMAT需要分别为后面的每个item指定一个格式化符号

    格式符:

        %c:显示字符的ASCII码

        %d,%i:显示十进制整数

        %e,%E:科学计数法数值显示

        %f:显示为浮点数

        %g,%G:以科学计数法或浮点形式显示数值

        %s:显示字符串

        %u:无符号整数

        %%:显示%自身

  换行符记得加上,不然看起来就很蠢了!!

         blob.png  

每个item都要有一个FORMAT,否则item就不成立了,不显示了

        blob.png    

    

    修饰符:

        #[.#]格式符:

            例如%3.1f==>第一个数字控制显示宽度,第二个数字表示小数点后的精度

        -:表示左对齐,默认为右对齐

        +:表示数值的符号 

        表示左对齐           

        blob.png        

        默认为右对齐

        blob.png

4.操作符

    算术运算操作符

        +,-,*,/,^,% 依次为加减乘除 次方取模

        -x:负值

        +x:转换为数值

    字符串操作符:没有符号的操作符,字符串连接

    赋值操作符

        =,+=,-=,*=,/=,^=,%=

    比较操作符:

        >,>=,<,<=,!=,==

 blob.png

模式匹配:

    ~:是否匹配

    !~:是否不匹配

逻辑操作符:

    &&: 与

    ||:或

     !:非

显示/etc/passwd文件中uid=0或者大于1000的行显示第1,3列,分隔符为”:“

blob.png

显示/etc/passwd文件中uid大于等于0小于等于1000的行显示第1,3列,分隔符为”:“

blob.png

显示/etc/passwd文件中uid不等于0的行显示第1,3列,分隔符为”:“

blob.png

函数调用:

     function_name(argu1,argu2,…..)  

条件表达式:

      selector ? if-true-expression:if-false-expression

      如果为真执行true,否则执行false

实例:

如果uid大于1000,则usertype为common,否则为system,,输出每行第一列及变量usertype

awk -F: '{$3>=1000?usertype="common":usertype="system";printf "%15s:%-s\n",$1,usertype}' /etc/passwd

blob.png

5.PATTERN

    1.empty:空模式,匹配每一行;

    2./regular expression/:仅处理被此处的模式匹配的行

     !/regular expression/:仅处理被此模式匹配的行之外的行

    例:显示以UUID开头的行,显示第一列,可个为分隔符

       显示不以UUID开头的行,显示第一列,可个为分隔符

    blob.png

    3.relational expression:关系表达式,结果有”真“有”假“,结果为”真“才会被处理

        真:结果为非0值,非空字符串

        假:结果为空字符串或0值

    示例:

    blob.png

    blob.png

    blob.png

    4.line ranges:行范围

        startline,endline: /pat1/,/pat2/不支持直接给出数字格式

    显示从以root开头的行开始,到以nobody开头的行结束,显示第一列,以”:“为分隔符

    blob.png

    显示行号小于10或者大于40的行,取出第一列,分隔符为”:“

    blob.png

    5.NEGIN/END模式

        BEGIN{}:仅在开始处理文件中的文本之前执行一次

        END{}:仅在文本处理完成之后执行一次 

    示例:

    blob.png

    blob.png     

  blob.png

     结果为真处理,为假不处理

    blob.png

    显示偶数行和奇数行

    blob.png

    此例来解释为何上面是奇数和偶数

    说明:i初始值为0,第一行i=!i,则i=1,结果为真,处理,所以上面第一行显示

    第二行时,i初始值为1,i=!i,则i=0,结果为假,不处理,所有上面第二行没显示,

    下面就是循环赋值了,每到技奇数行i=1,偶数行i=0,所以才有上面的效果

    (注意1为真,0为假,非1的结果就是假了,而非0的结果就是真了)

   blob.png

    如果我们使得i的初始值为真,那么结果就和上面的相反了,显示的是偶数行

   blob.png

    6.常用的action

          1.表达式Expressions

          2.控制语句Control statements  :if  while等

          3.组合语句Compound statements :组合语句

          4.输入语句input  statements

          5.输出语句outut  statements :print等

    7.控制语句

        if (condition) { statements } 

          if (condition) { statements }  else  { statements }

          while (condition) { statements }

          do  { statements } while (condition)

          for (expr1;expr2;expr3) { statements }

          break

          continue

          delete  array[index]

          delete array

          exit

          { statements  }

awk控制语句if-else

    语法:if(condition)  statements   [ else  statements]

        if(condition1) {statement1}else if(condition2) {statement2} esle{statement3}

    使用场景:对awk取得的整行或某个字段做条件判断

    示例:

    如果uid大于1000就显示此行中的第1,3列,分隔符为”:“

    blob.png

    如果uid大于1000则显示为conmmon user,否则显示system user,并显示第1,3列,分隔符为”:“

    blob.png

    说明 90分以下为very good 60-90为good,60分以下为不及格  blob.png

    以/dev开头的行,分隔符为%,取第一列,然后显示的行中默认可个为分隔符,最后一行如果大于20,则显示第1行和最后一行

    blob.png

awk控制语句=====while循环

语法:while(condition){statement}

条件为”真“,进入循环;条件为”假“,退出循环

使用场景:

    对一行内的多个字段注意类似处理时使用

    对数组中那个的各元素逐一处理时使用

示例:

    说明:文件为/etc/grub.cfg,匹配以任意数量的空格开头后面跟Linux16的行,做while循环,初始值i=1,判断题条件为i<NF(每行字段数),

      i++自增,打印内容为每行的每个字段,以及此字符个数。默认分隔符为" "

blob.png

    说明:在上面的基础上加了一个判断条件,字段中字符分个数大于等于10,打印内容为每行的每个字段,以及此字符个数。默认分隔符为" "

blob.png

awk控制语句=====do-while循环

语法:do {statement;…}while(condition)

意义:无论真假,至少执行一次循环

示例:

    blob.png

    说明不同:

    后面的i没有争议,那么i++和++i的却别就在于,先后顺序,

    第一个是先显示i,然后才自增赋值的,所以值为

    第二个是先自增赋值,然后才显示i的,所以值为1

    blob.png

awk控制语句===for循环

语法:for(expr1;expr2;expr3){statement;…}

常见用法:

    for(variable assignment;condition;iteration process){for-body}

特殊用法:能够遍历数组中的元素;

    语法: :for(var in array) {for-body}

示例:

awk '/^[[:space:]]*linux16/{for(i=1;i<=NF;i++) {print $i,length($i)}}' /etc/grub2.cfg

blob.png

性能比较:

time (awk 'BEGIN{total=0;for(i=0;i<=10000;i++){total+=i;};print total;}')
time(total=0;for i in {1..1000000};do total=$(($total+i));done;echo $total)
time(for ((i=0;i<=1000000;i++));do let total+=i;done;echo $total)

结果很显然是awk运算最快,想想也知道了,这章博客主要内容就是awk,做这个比较肯定想体现akw是有多牛逼咯

blob.png

awk控制语句====>switch语句

语法:swicth(expression){case VALUE1 or /REGEXP/:statement;case VALUE2 or /REGEXP2/:statement;…;default:statement}

break和continue

示例:

break表示当i=66的时候中断此循环,所以结果是1加到65

continue表示当i为偶数的时候终止了本轮循环,所以结果为奇数相加

blob.png

break[n]

continue[n]

next:

提前结束对本行处理而直接进入下一轮处理(awk自身循环)

说明:当uid为奇数时,提前结束本行,跳过本行要处理的,

blob.png

awk数值:array[index-expression]

index-expression:

    1.可使用任意字符串;字符串要使用双引号括起来

    2.如果某数组元素事先不存在,在引用时,awk会自动创建此元素,并将其值初始化为“空串”

若要判断数组中是否存在某元素,要使用“index in array”格式进行遍历

示例:

blob.png

 awk ‘!a[$0]++’ dupfile

若要遍历数组中的每个元素,要使用for循环

for(var in array) {for-body}

注意:var会遍历array的每个索引

示例:

blob.png

说明:统计tcp开头的单词中最后一字段出现次数

blob.png

说明:统计第一段ip出现的次数

blob.png

awk函数:

    rand():返回0和1之一个随机数

[root@localhost ~]# awk 'BEGIN{srand(); for (i=1;i<=10;i++)print int(rand()*100) }'

blob.png

字符串处理:

length([s]):返回指定字符串的长度

sub(r,s,[t]):对t字符串进行搜索r表示的模式匹配的内容,并将第一个匹配的内容替换成s

    echo "2008:08:08 08:08:08" | awk 'sub(/:/,“-",$1)'

gsub(r,s,[t]):对t字符串进行搜索r表示的模式匹配的内容,并全部替换为s所表示的内容

    echo "2008:08:08 08:08:08" | awk ‘gsub(/:/,"",$1)'

blob.png

split(s,array ,[r]):以r为分隔符,切割字符s,并将切割后的结果保存至array所表示的数组中,第一个索引值为1

第二个索引值为2…

blob.png

自定义函数

格式

    function name (parameter,parameter,….){

            statements

            return exprossion

    }

示例:

#!/bin/bash
function max(v1,v2) {
v1>v2?var=v1:var=v2
return var
}
BEGIN{a=3;b=2;print max(a,b)}

blob.png

  1 #!/bin/bash
  2 function max(v1,v2) {
  3 v1>v2?var=v1:var=v2
  4 return var
  5 }
  6 BEGIN{print max(a,b)}

blob.png

awk中调用shell命令

system命令

空格是awk中的字符串连接符,如果system中需要使用awk中的变量可以使用空格分隔,或者说除了awk

的变量外其他的一律用“”引用起来

blob.png

awk脚本

将awk程序写成脚本,直接调用或执行

示例:

blob.png

blob.png

向awk脚本传递参数

格式:

    awkfile var=value var2=value2… Inputfile

[root@localhost bin]# cat test.awk 
#!/bin/awk -f
{if($3<=min||$3>=max)print $1,$3}
[root@localhost bin]# test.awk -F: min=10 max=1000 /etc/passwd

blob.png

练习

1 、 统计/etc/fstab文件中每个文件系统类型出现 的次数

awk '/^UUID/{fs[$3]++}END{for(i in fs) {print i,fs[i]}}' /etc/fstab

blob.png

2、 、 统计/etc/fstab 文件中每个单词出现的次数

[root@localhost bin]# awk '{for(i=1;i<=NF;i++){count[$i]++}}END{for(i in count) {print i,count[i]}}' /etc/fstab
man 1
and/or 1
/mnt 1
maintained 1
xfs 4
14:09:19 1
UUID=b39702a5-31f8-4fca-96cc-3389a0a58059 1
Accessible 1
# 7
are 1
defaults 5
blkid(8) 1
/ 1
0 13
See 1
3 1
Mon 1
Created 1
on 1
usrquota,grpquota 1
mount(8) 1
ext4 2
acl 1
anaconda 1
fstab(5), 1
/boot 1
/testdir 1
/usr 1
UUID=bd915a87-493a-415b-8d2f-8cedaab84792 1
findfs(8), 1
2016 1
/home 1
'/dev/disk' 1
UUID=5bc0405e-cf7a-4d60-8c0c-a6daa1dd71d2 1
by 2
/etc/fstab 1
UUID=12294f2d-4b7d-4f64-a8b7-1522fe51d0b2 1
pages 1
UUID=d8150c22-3804-4d3e-bd18-8f44e93bb978 1
more 1
25 1
info 1
UUID=8d687919-88d4-4c2a-9e0b-473cd13bb785 1
swap 2
Jul 1
UUID=14efdeb1-9880-49dc-aaa0-321c4eb4816a 1
filesystems, 1
reference, 1
for 1
under 1

原创文章,作者:qiuwei,如若转载,请注明出处:http://www.178linux.com/47950