awk 是一个报告生成器 , 文本编辑器 , 同时自身也是一种编程语言 ,它支持条件判断、数组、循环等功能

    

    功能 : 对文本数据进行汇总处理 , 对数据进行排版

    注 : awk只能对读入到内存中的信息进行处理 , 无法对内容所在的原文件内容进行修改 , 想要修改原文件内容可以使用sed命令来改


    grep 、sed、awk被称为linux中的"三剑客" , 相对这三者来说 : grep 更适合单纯的查找或匹配文本 ;sed  更适合编辑匹配到的文本 ;awk  更适合对文本进行较复杂格式处理

    grep , sed 以及跟多的Linux 的 bash 用法可参考上篇博客 : https://blog.51cto.com/14181896/2359243




 一 .awk语法格式及基本使用


语法一 : awk  [选项]  '/匹配模式/{处理动作1 , 处理动作2...}'   文件名

语法二 : awk  [选项]  'BEGIN{动作}{处理动作1 , 处理动作2...}END{动作}'   文件名


说明 : BEGIN 是指在读awk指定的文件之前要执行的操作 , END 是指在awk读完指定的文件之后执行的操作 .


实例 : 显示 /etc/passwd 文件中以 : (冒号)分隔的第一列内容 :

Shell(6)- awk 命令用法_第1张图片

               

说明 : 上图命令中 -F : 指定以冒号分隔 , print $1 表示打印出第一列 .  如果不指示符号 , 默认符号为空格 , 可以使用命令 awk '{print  $1}'  /etc/passwd   对比一下上面的命令显示出来的结果 .

              

awk的BEGIN , END 语句用法 :

在命令行中执行 : awk  'BEGIN{print  "welcome  to  awk"}' 结果如下 :

image.png

执行命令 : awk -F: 'BEGIN{print "welcome to awk"}{print $1}END{print "bye bye"}' /etc/passwd  ,从下图可以看出 , 打印出来的 /etc/passwd文件的第一列的开头和节为的内容分别为命令 BEGIN 和 END 语句显示的内容 :

Shell(6)- awk 命令用法_第2张图片

image.png



 二 . awk 的内置变量


关于awk的内置变量常见的有$0 , FS , OFS :

        

$0        # 保存当前的整行记录的内容

例 : awk  -F:  '{print  $0}'   /etc/passwd , 这条命令显示的是 /etc/passwd 文件的所有内容

image.png         

FS       # 输入字段分隔符 , 默认是空白

例 : awk  'BEGIN{FS=":"}{print $1,$2}'  /etc/passwd

Shell(6)- awk 命令用法_第3张图片 

OFS     #输出字段分隔符 , 默认为空白

例: awk  'BEGIN{FS=":";OFS="@"}{print $1,$2}'  /etc/passwd

Shell(6)- awk 命令用法_第4张图片

     

    除了这三种常见的内置变量之外 , 内置变量还有 : 

          

NR    #记录号 , 每处理完一条记录 , NR值就加1 , 记录的是文件的总值 

             可以使用命令 : awk  -F:  '{print NR,$0}'  /etc/passwd 查看效果

FNR   #处理多个文件时分别统计自己的NR值

             可以使用命令 : awk  -F:  '{print NR,$0}'  /etc/passwd  /etc/gshasow 查看效果

NF    #表示当前行的字段数(number field)

             可以使用命令 : awk  -F:  '{print NF,$0}'  /etc/passwd  查看效果 

RS     #输入记录分隔符(记录是是行与行之间的分隔) , 默认是一个换行符

             可以使用命令 : awk  -F:  'BEGIN{RS=":"}{print}'  /etc/passwd  查看效果

ORS   #输出记录分隔符

             可以使用命令 : awk 'BEGIN{ORS=":"}{print}'  /etc/passwd   查看效果

           

          以上内置函数不一一举例 , 自行查看效果 ..




 三 . awk的逻辑控制语句

           

 前面说到 , awk本身就为一门编程语言 , 所以它本身也自带逻辑控制语句 , 如 if 条件语句 ,for 循环语句等 .

    

1 . 条件判断 if :

格式 : {if(表达式) {语句 , 语句 ....}}

例 : awk  -F:  '{if($4>999){print $0}}'  /etc/passwd      # 显示/etc/passwd 文件中gid大于999的信息

 Shell(6)- awk 命令用法_第5张图片

              

 问 : 统计/etc/passwd文件中登录shell为/bin/bash有多少个?

 答 : awk  -F:  '{if($NF=="/bin/bash"){i++}else{j++}}END{print "不是/bin/bash的有 :"j "\n是/bin/bash的有:"i}' /etc/passwd (建议掌握)

 image.png

 注: awk调用内置变量值的时候需要用$变量名 , 而调用自定义变量值的时候不需要$符号 .

     

2 . 循环语句:

举例说明用法 :

while : 打印1-5数字         awk 'BEGIN{i=1;while(i<=5){print i ;i++}}'

Shell(6)- awk 命令用法_第6张图片

for :  将文件/etc/passwd每一行打印10次      awk -F: '{for(i=1i<=10;i++){print $0}}'  /etc/passwd




 四 . 数组


例 :统计passwd文件中各种shell类型
awk -F: '{shell[$NF]++} END{for(i in shell){print i,shell[i]}}' /etc/passwd

Shell(6)- awk 命令用法_第7张图片

  shell[$NF]++定义了一个名称为shell的数组,$NF(即number  field行中的字段数)在passwd中是shell名称,for(i in shell) print i,shell[i],用for循环取出数据来,这时候i取的是下标,shell[i]是里面存储的数据,也是$NF出现的次数

  



 五 . print

       

1 . print输出 :


要点 : 各个输出字段之间用逗号做分隔 , 而输出默认是以空格做分隔

print 后面如果不指定字段 , 那么会打印一整行

print 输出是默认是有换行符的

       

例 : 打印与文件内容无关的
awk  '{print "aaa"}'   /etc/passwd    根据/etc/passwd内容的行数来循环执行print命令
Shell(6)- awk 命令用法_第8张图片

 \n换行符
awk -F: '{print $1"\n"$2}'  /etc/passwd

Shell(6)- awk 命令用法_第9张图片               

 \t制表符
awk -F: '{print $1"\t"$2}'  /etc/passwd
image.png               

打印一句话:root用户的uid是0
awk -F: '/^root/{print $1"的uid是"$3}'   /etc/passwd

 image.png

2 . printf格式输出 :

            

作用 : 可以格式化(format)输出 , 默认不换行

要点 :  printf需要指定格式(format)
           格式(format)是用来指定后面每个item(条、项目)的输出格式的
           printf默认不会自动打印换行符,需要自己动手添加"\n"
           printf默认没有输出字段分隔符


使用格式 : printf  format  itme1

format的指示符都是以%开头的 , 后面跟一个字符 :

                      %s : 表示字符串

                      %d : 十进制整数

                      %f : 表示浮点数(float) , 也就是小数  (%4.2f  其中4表示总显示宽度 , 2表示小数的尾数)

                      %x : (16进制)  %o : (8进制)

                      修饰符 : %Ns  N表示显示宽度(是一个数字) 

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


用法 : 例 格式化输出/etc/passwd文件中的用户名 , uid , gid 三列

awk -F: '{printf "%-15s %-5d %-5d\n",$1,$3,$4}'     /etc/passwd

image.png                                            执行下面两条语句看对比 :        

echo  -e  'hello\nwelcome\nlinux\n1234567890' | awk '{printf "%10s\n",$1}'  
echo  -e  'hello\nwelcome\nlinux\n1234567890' | awk '{printf "%8s\n",$1}'

Shell(6)- awk 命令用法_第10张图片

               



 六 . awk的比较表达式


比较表达式采用的的是关系运算符 , 用于比较数字与字符串 .


数字与字符串使用的运算符有 :

<  大于     <=  小于等于     =  赋值     ==  相等     !=  不相等     >  大于     >=  大于等于


例 : 打印 /etc/passwd 文件中的uid=0的账号信息  (图中命令没有写print , 是因为awk会默认执行print命令)

image.png      

以冒号分隔打印/etc/passwd文件第七列为 /bin/bash的行

Shell(6)- awk 命令用法_第11张图片




 七 . awk的匹配模式


/key/                        #匹配key关键字

x ~ /key/                  #匹配正则  , 其中key可以是正则表达式 , x通常是$1~$n

(awk -F: '$1~/ro/{print $0}'  /etc/passwd        #打印/etc/passwd第一列包含ro字符的内容行)

x !~/key/                  #不匹配正则

(awk -F: '$7 !~/nologin$/'  /etc/passwd      #打印/etc/passwd中第7列(即登录shell)除了nologin结尾的用户信息)


常见模式 :

1. 空模式   (例 : awk -F:  '{print $1}'  /etc/passwd     #打印文件/etc/passwd第一列 , 不匹配)

Shell(6)- awk 命令用法_第12张图片

2. 固定模式地址  (例 : awk -F: '$1~/^ro/{print $1}'  /etc/passwd   #打印第一列以ro开头的第一列)

image.png

3. 范围模式地址  (例 : awk -F: '/^ro/,/^lp/{print $1}'  /etc/passwd   #打印以ro开头到lp开头的第1列内容)

Shell(6)- awk 命令用法_第13张图片

  

注 : awk中不支持行号定址 (反例 : awk -F: '2,5{print $1}' /etc/passwd) ;但用awk的内置变量NR就可以实现类似行号定址的功能 ,如 : (awk 'NR==2,NR==5'  /etc/passwd    # 输出/etc/passwd文件的第2行至第5行)




 八 . 赋值运算


        a++                 #等同于 a=a+1

        a+=5               #等于a=a+5

        a+=$n             #等同于a=a+$n

 

例 : 对 /etc/passwd 文件中的 uid 做累加计算

image.png


 以上就是awk比较全面的介绍及如门操作  !!!