万能的AWK

awk:文本三剑客之一

#报告生成器,主要用来实现格式化文本输出,它能够实现在处理文本文件时对文档中的某字段有条件显示并以非常美观的文本;

它是编程语言的解释器;它也是一种完整的编程语言,它支持条件判断、循环、变量、数组、函数等等各种各样的编程语言所能实现的功能。

用法:awk [options] ‘program’ FILE …

   program: PATTERN{ACTION STATEMENTS}

               PATTERN:awk在数据中查找的内容

       ACTION STATEMENTS:动作语句,对查找的内容执行的一系列命令,多为awk内置的命令print和printf;多个语句之间用分号分隔;     

          注意:program中的字符串要加双引号。                                                    

      选项:

  -F:指明从文件中输入数据时用到的字段分隔符;默认空白字符且不限制空白字符的个数,即同一行中一个空白字符、两个空白字符、三个空白字符等都是分隔符;

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

万能的AWK

awk的print子命令

       用法:print item1, item2, …

       要点:

   输出时默认以空白为分隔符;

   输出的各item可以字符串,也可以是数值,还可以是当前记录的字段(例如$1、$2等等)、变量或awk的表达式;其中数值在输出时会被隐式转换成字符串以字符格式输出,但该数值参与运算时依然是数值;变量要想替换值一般不能用引号引起来;

   省略item相当于print $0(即打印整行);

万能的AWK

备注:打印/etc/fstab文件中后5行的第2和4字段;

AWK的变量:有内建变量和自定义变量两类;awk中引用变量不需要加$,只有引用字段变量时才用加$,例如$1、$2;

      ①内建变量

        FS:input field seperator,输入字段分隔符,默认为空白字符;

        OFS:output field seperator,输出字段分隔符,默认为空白字符;

        RS:input record seperator,输入行分隔符,默认为换行符;

        ORS:output record seperator,输出行分隔符,默认为换行符;

        NF:number of field,每行字段数量

        {print NF}:打印行的字段数量

        {print $NF}:打印行的最后一个字段值

        NR:number of record, 行数或行号

        FNR:各文件分别计数;行数或行号

        FILENAME:文件名;

        ARGC:命令行参数的个数;

        ARGV:保存了命令行参数的数组;

  修改内建变量默认值:例如,#awk -v FS=”:”或#awk -F:(修改输入分隔符为冒号)

万能的AWK

可以看到效果。。。。。。

②自定义变量

       有两种方法:

       1>-v var=value

         变量名区分字符大小写;

       2>在program中直接定义

万能的AWK

awk的printf子命令:格式化输出

       用法:printf FORMAT, item1, item2, …

       要点:

           FORMAT必须给出;

           FORMAT中需要分别为后面的每个item指定一个格式符

           不会自动换行需要显式给出换行控制符\n

               格式符:每一个格式符还可以有它的修饰符

                   %c: 显示字符的ASCII码;

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

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

                   %f:显示为浮点数;

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

                   %s:显示字符串;

                   %u:无符号整数;

                   %%: 显示%自身;

               修饰符:用于格式符前面控制格式符显示的机制

    #[.#]:第一个数字控制显示的宽度;第二个#表示小数点后的精度,例如%3.1f

            -: 左对齐,默认右对齐;

            +:显示数值的符号;

       注意:几乎所有的编程语言都支持格式化输出(包括bash)bash中也支持使用printprintf,不仅仅是echo

万能的AWK

awk中的操作符

       ①算术操作符:

         x+y, x-y, x*y, x/y, x^y, x%y:加,减,乘,除,次方,取模

         -x:正数转换为负数;

         +x: 字符串转换为数值;

       ②字符串操作符:默认只有一个,即没有符号的操作符(表示字符串连接);

       ③赋值操作符:=, +=, -=, *=, /=, %=, ^=(次方等),++, —

       ④比较操作符:>, >=, <, <=, !=, ==

       ⑤模式匹配符:

 ~:是否匹配

 !~:是否不匹配

       ⑥逻辑操作符:&&,||,!

       ⑦函数调用:规范的函数调用方式,区别于bash中的函数调用;

         function_name(argu1, argu2, …):“argu1, argu2, …”为向函数传递的参数;

       ⑧条件表达式:selector?if-true-expression:if-false-expression

         selector是条件表达式,若selector为真则执行if-true-expression,否则执行if-false-expression;

PATTERN:实现地址定界的功能

       ①empty:空模式,即匹配每一行;

       ②/regular expression/:正则表达式,仅处理能够被此处的正则表达式匹配到的行;“//”为模式符号,凡是正则表达式都要放在模式符号中;

       ③relational expression: 关系表达式,结果有“真”有“假”,结果为“真”才会被处理;结果为非0值或非空字符串为真,否则为假;

       ④line ranges:行范围;

         startline,endline:/pat1/,/pat2/

         注意:不支持直接给出数字的格式

       ⑤BEGIN/END模式

 BEGIN{}: 仅在开始处理文件中的文本之前执行一次,比如打印表头;若不对文件做处理则运行在BEGIN模式中;

 END{}:仅在文本处理完成之后命令结束之前执行一次,比如打印处理结果;

万能的AWK

万能的AWK

万能的AWK

蛮有意思的0.0

常用的action,有如下几类;

       ①Expressions:表达式,例如“a=6”;

       ②Control statements:控制语句,例如if, while等;

       ③Compound statements:组合语句,即把多个语句组合起来当一个代码块,通常用花括号括起来;

       ④Input statements:输入语句;

       ⑤Output statements:输出语句;

 

  awk控制语句

       if(condition) {statments}(只有一个语句花括号可以省略,下同):

       if(condition) {statments} else {statements}

       while(conditon) {statments}

       do {statements} while(condition)

       for(expr1;expr2;expr3) {statements}

       break

       continue

       delete array[index]:删除数组中的某个元素

       delete array:删除整个数组

       exit

       {statements}

控制语句

  1)if-else:很少用到多分支语句

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

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

2)while循环

       语法:while(condition) statement,条件“真”,进入循环;条件“假”,退出循环;若首次条件判断为假,则循环体执行0次。

       使用场景:对一行内的多个字段逐一进行类似处理时以及对数组中的各元素逐一进行类似处理时使用

 示例:
            awk ‘BEGIN{i=1;sum=0;while(i<=100){sum+=i;i++};print sum}’
            awk ‘/^[[:space:]]*linux16/{i=1;while(i<=NF) {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

3)do-while循环

       语法:do statement while(condition),与while的区别在于先执行一次循环体再判断;

 

1+2+3+….100,计算累加的和?多种方法实现
        1.awk ‘BEGIN{ total=0;i=0;do{ total+=i;i++;}while(i<=100);print total}’
        2.awk ‘BEGIN{for(i=1;i<=100;i++){ sum+=i}print sum}’
        3.awk ‘BEGIN{i=1;sum=0;while(i<=100){sum+=i;i++};print sum}’
        4.seq -s “+” 100 |bc
        5.echo `seq 100|tr ‘\n’ ‘+’`0|bc
        6.echo {1..100}|tr ‘ ‘ “+” |bc
        7.for ((i=1,sum=0;i<=100;i++));do let sum+=i;done;echo $sum
        8.i=1;sum=0;while [ $i -le 100 ];do let sum+=i;let i++;done;echo $sum

  4)for循环:比while循环更简洁更易懂

      语法:for(expr1;expr2;expr3) statement

      详解:for(variable assignment变量赋值;condition条件判断;iteration process变量迭代) {for-body循环体}

 

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

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

 示例:

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

5)switch语句:多分支if语句,类似bash中case语句,但是关键字不同;常用于字符串等值比较或模式匹配判断;

      语法:switch(expression) {case VALUE1 or /REGEXP/: statement; case VALUE2 or /REGEXP2/: statement; …; default: statement}:expression和“VALUE1 or /REGEXP/”

       

  6)break和continue

       break [n]:跳出n层循环,控制行内循环(即字段间循环);

       continue:跳出当前循环直接进入下一轮循环,控制行内循环;

 

  7)next:控制awk的内生循环(即行间循环)提前结束对本行的处理而直接进入下一行;

      备注:使用while、do-while、for编写的循环控制awk的行内循环;

     

8)array:较多使用关联数组;

       关联数组:array[index-expression]

           index-expression:

        ①可使用任意字符串,字符串要加双引号;

        ②如果某数组元素事先不存在,在引用时awk会自动创建此元素并将其值初始化为“空串”,当把该“空串”当数值使用时其值为零;

       数组元素赋值详见“2016.01.05-bash编程之数组和字符串处理(1)”

       数组元素引用使用print而非$;

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

       遍历数组中的每个元素要使用for循环,格式为“for(var in array) {for-body}”,var会遍历array的每个索引;

 示例:
        weekdays[“mon”]=”Monday”;awk ‘BEGIN{weekdays[“mon”]=”Monday”;weekdays[“tue”]=”Tuesday”;print weekdays[“mon”]}’
        awk ‘!arr[$0]++’ dupfile         #去重,所有行都第一次打印
        awk ‘{!arr[$0]++;print $0, arr[$0]}’ dupfile          #跟踪执行过程
        awk -F: ‘{arr[$1]=$3;print arr[$1]}’ /etc/passwd
        awk -F: ‘{arr[$1]=$0;print arr[NR]}’ /etc/passwd
        awk -v n=0 ‘!n{print}’ /etc/passwd
    若要遍历数组中的每个元素,要使用for循环
        for(var in array) {for-body}
    注意: var会遍历array的每个索引
示例:
        awk ‘BEGIN{sum=0;for(i=1;i<=100;i++){if(i%2==0)continue;sum+=i}print sum}’
        awk ‘BEGIN{sum=0;for(i=1;i<=100;i++){if(i==66)break;sum+=i}print sum}’
        awk -F: ‘{if($3%2!=0) next; print $1,$3}’ /etc/passwd                              #打印奇数行
        awk -F: ‘{if($3%2!=1) next; print $1,$3}’ /etc/passwd                             #打印偶数行
        awk -F: ‘{if($3%2!=0) {next;} else {print $1,$3}}’ /etc/passwd

函数

  1)内置函数

       数值处理:

           rand():返回0和1之间一个随机数,此处的随机指首次随机;

       字符串处理:

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

           sub(r,s,[,t]):以r表示的模式来查找t所表示的字符中的匹配的内容,并将其第一次出现替换为s所表示的内容;该功能sed和grep更易用;

   gsub(r,s,[,t]):以r表示的模式来查找t所表示的字符中的匹配的内容,并将其所有出现均替换为s所表示的内容;该功能sed和grep更易用;

           split(s,a[,r]):以r为分隔符切割字符s并将切割后的结果保存至a所表示的数组中;awk中的数组下标从1开始;

  2)自定义函数:极少用;

数值处理:
        rand():返回0和1之间一个随机数
        awk ‘BEGIN{srand(); for (i=1;i<=10;i++)print int(rand()*100) }’
            srand() 是生成种子,rand才可以生成随机数,二者需要配合使用
            int() 可以对浮点数取整
    字符串处理:
        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(/:/,”-“,$0)’
            echo “2008:08:08 08:08:08” | awk ‘gsub(“:”,”-“,$0)’
        split(s,array,[r]):以r为分隔符,切割字符串s,并将切割后的结果保存至array所表示的数组中,第一个索引值为1,第二个索引值为2,…
            netstat -tan | awk ‘/^tcp\>/{split($5,ip,”:”);count[ip[1]]++}END{for (i in count) {print i,count[i]}}’

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

(0)
All wellAll well
上一篇 2017-04-22
下一篇 2017-04-22

相关推荐

  • N26-第一周作业

    1、描述计算机的组成及其功能;  计算机组成部分分为硬件及软件。  硬件:  计算机硬件主要有五大部分组成:运算器、控制器、存储器、输入设备、输出设备;  1)运算器、控制器,统称为处理器,也就是CPU:    主要功能是对各种数据进行运算,包括加、减、乘、除的算术运算,还包括进行逻辑判断的能力,如…

    Linux干货 2016-12-31
  • mysql-yum安装多实例

    1.安装包 yum install mariadb-server 2.创建文件 3 分别生成3306,3307,3308数库文件 4.复制主配置文件并分别修改端口路径 5.准备一个启动脚本并开启服务 /mysqldb/3307/mysqld start 6.用mysql -S 命令进入    

    2018-01-28
  • Apc缓存Opcode

    1、PHP执行 PHP的运行阶段也分成三个阶段: Parse。语法分析阶段。 Compile。编译产出opcode中间码。 Execute。运行,动态运行进行输出。                            …

    Linux干货 2015-04-10
  • Linux文件类型以及颜色标识

    1、Linux文件类型介绍   Linux系统不同于window系统,两者文件类型也有很大的差异。Linux文件类型和Linux文件的文件名所代表的意义是两个不同的概念。我们通过一般应用程序而创建的比如file.txt、file.tar.gz,这些文件虽然要用不同的程序来打开,但放在Linux文件类型中衡量的话,大多是常规文件(也被称为普…

    Linux干货 2016-10-17
  • python面向对象第二周魔术方法详解

    魔法方法及其使用__开头和结束的方法,定义外部没有办法直接调用,但会有影响使用运算符号的魔法方法, + ,-,*,/,%,//,**, __add__,__sub__,__mul__,__truediv__,__mod__,__floordiv__,__pow__,__divmod__(?),系统内部对于数值型,字符串型,容器内型都定义了其中部分或者全部的运…

    Linux干货 2017-11-22
  • Linux 命令行返回状态

    linux 执行命令后会返回一个状态码 命令执行成功返回0: 当删除一个文件并删除成功时返回的状态码为0 [root@localhost 1]# rm -rf 1_1 [root@localhost 1]# echo $? 0 命令执行失败返回1-255 当把 文件夹 1_1 重命名为1_2失败后状态码为1 [root@localhost 1]# mv 1_…

    Linux干货 2017-08-28