awk学习笔记

一、linux的文本处理器三剑客

  文本过滤器:grep、egrep、fgrep

  行编辑器:sed(模式空间;保持空间)

  报表生成器:awk(格式化文本输出)gawk

awk的工作流程:

从文本中读取一行内容,根据指定的分隔符;将读入的一行内容分隔成字段,然后格式化输出指定的字段

1.png

二、awk的命令相关的参数及用法

  1、基本用法:

awk [options]  'program' file1,file2,.....
  options常用选项:
       -F[]:指定分隔符,使用[]可以指定多个分隔符
       -v var=varl:变量赋值
  program组成:
      PATTERN {ACTION STATEMENT},由语句组成,语句分隔符是";"
      ACTION:print,printf

例:使用awk对/etc/paswd文件进行编辑,赋值给变量test,利用-F指定分隔符":",使用print打印出指定内容

2.png

 2、awk的常用输出命令:print

   用法:print  item1,item2,….

 注意要点:

  ①各item直接使用逗号分隔,而输出时则使用输出分隔符进行分隔

  ②输出时各item可以是字符串或数值、当前记录的字段($n)、变量或awk的表达式;数值会被隐式转换字符输出   ③print的item如果省略,相当于print $0,若输出“空白”,则使用print "";

 3、awk变量

内置变量:
    FS: input field separator;输入分隔符,默认为空白字符
    RS: input record separator;输入换行符,默认为空白字符
    OFS: output field separator;输出分隔符,默认为空白字符
    ORS: output record separator;输出换行符,默认为空白字符
    NF: 当前行的字段数
    NR: 行数,所有文件统一计数
    FNR: 行数,各文件分别计数
    FILENAME: 当前文件名
    ARGC: 命令行的参数的个数
    ARGV: 数组,保存命令行的所有参数

自定义变量:
 -v VAR=VAL
  定义变量的位置:
   可以在program中定义
     可以使用-v 定义

  例1:利用FS,RS,OFS,ORS,对/etc/passwd进行文本处理

3.png

 例2:统计当前行的字段数

  4.png

  例3:统计文件的行数:

  5.png

  6.png

   例4:统计命令的个数和数组

  7.png

  8.png

  例5:自定义变量

  9.png

4、printf命令:

格式: printf format item1,item2,....
  注意要点:
     1) format是必须的
     2)不会自动换行,需显示给定换行符
     3)format中需要分别为后面的每个item指定一个格式符

格式符:都以%开始,后面跟一个字符
    %c: 显示字符的ASCII码
    %d,%i: 显示十进制整数
    %e,%E:以科学计数法显示数值
    %f:显示浮点数
    %g,%G:以科学计数法格式或浮点数格式显示数值
    %s:字符串
    %u:无符号的整数
    %%:显示%自身
 
 修饰符:
    #[.#]: 第一个#显示字符宽度,例如%20s;第二个#表示小数点后的精度
    -:左对齐
    +:显示数值符号
    
 操作符:
    算术运算操作符:
       x+y, x-y, x*y, x/y, x^y, x%y
       -x: 负值
       +x: 转换为数值
  
    字符串操作符:字符串连接
  
    赋值操作符:
       =, +=, -=, *=, %=, /=, ^=, ++, --
      
    比较操作符:
       <, >, <=, =>, ==, !=
         
    模式匹配符:
      ~ ,!~
      
    逻辑操作符:
         &&   || 
         
    条件表达式:
         selector? if-true-expression:if-false-expression
     
     函数调用:
         function_name (argu1,argu2,...)

   例1:格式符

 0.png

   例2:条件表达式

11.png

 5、PATTERN:

   1)/regular expression/:进出了能够被/regluar expression/匹配到的行

   12.png

   2)relational expression:关系表达式,有真假之分,一般来说,其结果为非0或非空字符串时为"真",否则为"假"

  13.png

  3)line ranges: 行范围,类似sed或vim的地址定界法:startline,endline

  14.png

  4)BEGIN/END:特殊模式,仅在awk运行程序之前执行一次BEGIN或仅在awk运行程序后执行一次END    15.png

  5)empty:空模式,任意匹配

  16.png

 6、常用的action:

Expression
Control statements
Compound statements
input statemenets
output statements

 7、控制语句:

   1)if语句:对awk取得的整行或行中的字段做条件判断
       语法:if (condition) statement [else statement]
             if (condition) {statement; [else {statement};]
  例:
awk -F: '{if (($3)>=500) {print $1,"is command user"} else{print $1,"is admin user."}}' /etc/passwd
   2)while循环:通常在当前行的字段间进行循环
       语法:while (condition)  statement
              while  (condition)  {statement}
  例:# awk  '{i=1;while(i<=NF){printf "%20s:%s\n",$i,length($i);i++}}'  /etc/issue
              CentOS:6
             release:7
                 6.6:3
              Kernel:6
                  \r:2
                  on:2
                  an:2
                  \m:2
   3)do-while循环:至少执行一次循环体
         语法:do statement  while (condition)
            do {do-while-body} while (condition)
   4)for循环:
      语法: for (expr1;expr2;expr3) statement
          for (expr1;expr2;expr3) {statement}
     例:#awk '{for (i=1;i<=NF;i++) {printf "%s:%d\n",$2,length($i)}}' /etc/issue
          release:6
          release:7
          release:3
          release:7
          \r:6
          \r:2
          \r:2
          \r:2
          \r:2
         
         for 循环在awk中有一个功能专用于遍历数组元素
             语法:for (var in arry)  {for-body}
   5)swithc:是gawk特有的,awk没有此功能
   语法:switch (expression) {case VALUE or /REGEXP/:statement;.......;default:statementN}
   6)break and continue
     break[n]: 退出内存[n]循环
     continue[n]: 提前结束本轮循环,直接进入下轮循环
   7)netx:提前结束对本行的处理,而进入下一行的处理
     例:# awk '{if (NF%2!=0) next; {print $0}}' /etc/issue
      CentOS release 6.6 (Final)
   8)arry数组:
    关联数组:arry[index-expression],其中index-expression可以使用任意字符;
    如果某数组元素事先不存在,在引用时,awk会自动创建此元素,将其初时为空串
    ;因此如果要判断数组中是否存在某元素,要使用"index in arry" 进行
    要遍历数组中的每个元素,使用: for (var in arry) {for body}
   注意:var会遍历arry的每一个索引,print arry[var]
   例:统计netstat中各状态各出现多少次
    # netstat -tan | awk '/^tcp/{state[$NF]++}END{for (i in state){print i,state[i]}}'
     ESTABLISHED 1
     LISTEN 28
   9)函数
    (1)内置函数
     数值处理:
        rand(): 返回0和1之间的一个随机数
             
     字符串处理:
      length([s]):返回指定字符串的长度
      sub(r,s,[,t]):以r表示的模式来查找t字符串中的匹配,将其第一次出现替换为同s所表示字符串
       gsub(r,s[,t]):以r表示的模式来查找t字符串中的匹配,将其所有出现替换为同s所表示字符串
      split(s,a[,r]):以r为分隔符切割字符串s,并将切割的结果保存至a表示的数组中
       substr(s,i,[,n]):从s表示的字符串中取字串,从i开始,去n个字符
             
     时间函数:
      systime():取时间戳
       # awk 'BEGIN{print systime()}'
       1434125151          
                    
       位运行函数:
       and(v1,v2)
                 
   (2)自定义函数:
     funciton f_name(p,q)
       {
       ...............
       }

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