码迷,mamicode.com
首页 > 其他好文 > 详细

awk工具的使用

时间:2018-04-17 14:21:06      阅读:163      评论:0      收藏:0      [点我收藏+]

标签:linux   awk   文本处理   

awk是一个功能强大的文本分析工具,在centos中,awk与gawk是同一个命令 

~]# ls -l /usr/bin/awk
lrwxrwxrwx. 1 root root 4 10月 14 2017 /usr/bin/awk -> gawk

可以看到,awk文件是gawk文件的一个符号链接


格式:

    gawk [options] 'program' file ...        

        program:[/PATTERN/]{ACTION statement;...}

            PATTERN部分:决定动作语句何时触发以及通过什么事件触发

 

    常用选项:

-f,--file program-file:从指定的文件中加载program语句块,而不是通过命令行给出相关的程序内容;

-F,--field-separator fs:指定字段的输入分隔符;默认是空白字符;

-v,--assign var=val:用于声明自定义变量并为变量赋值;

                

基本概念:    

    1.分隔符:

        输入分隔符:

    awk对数据进行处理时,会根据特定的标识符号对数据进行分段处理,这种标识符号就称为"输入分隔符",默认的输入分隔符是空白字符;如果指定的分隔符并没有被数据包括,则只有换行分隔符有效;


        输出分隔符:

            awk对数据处理完成后,会以特定的标识符号对各个字段进行连接后输出,这种标识符号就称为"输出分隔符",默认的输出分隔符是空白字符;


    2.记录:由换行符进行分隔的数据中一行,就称为一条记录(Record);通常在使用awk处理数据时,使用内置变量$0来保存整个记录的内容;


    3.字段:经过分隔符分隔之后的每一个数据分段,都成为一个字段(Field);通常在使用awk处理数据时,使用$1,$2...$NF等内置变量来存储各个字段的数据;



awk的工作原理:

    1.首先,执行BEGIN{ACTION statement;...}语句块中的语句;

    2.其次,从文件中或着标准输入读取一行,根据PATTERN的匹配结果执行后面的ACTION语句块中的内容;然后逐行重复该过程已完成数据处理,直到数据全部被读取完毕;

    3.最后,在所有的语句块都执行完成之后,退出awk进程之前,执行END{ACTION statement;...}语句块中的语句;


    注意:

1) BEGIN语句块在awk开始处理数据内容之前就被执行;通常用于生成表头;此语句块是可选语句块;

2) END语句块在处理完所有的数据之后,才会被执行;通常用于数据汇总;此语句块是可选语句块;

3) PATTERN语句块中的通用命令是最重要的部分,因此PATTERN语句块不能省略,但其中的ACTION可以省略,如果省略,则默认执行print动作,即:显示数据的各行;

4) awk在执行PATTERN语句块时,默认循环遍历数据中的各个记录;


awk常用用法:

    1.变量:

        1)内建变量:           

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

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

                示例:指定输入字段分隔符为":",输出字段分隔符为":",输出/etc/passwd文件中每行的第1、3、7个字段

awk -v FS=':' -v OFS=':' '{print $1,$3,$7}' /etc/passwd

                    技术分享图片


                    其中,使用"-F:"选项效果与"-v FS=':'"相同

                    技术分享图片

            

            RS:输入记录(行)分隔符,默认为换行符;

注意:即使指定了额外的输入记录分隔符,原有的换行符依然有效;

    ORS:输出记录分隔符,默认为换行符;

                示例:指定输入记录分隔符为":",输出记录分隔符为"#",输出每个记录的内容:

awk -v RS=':' -v ORS='#' '{print $0}' /etc/passwd

                     技术分享图片


            

            NF:每一行中的字段的总数;

示例:显示指定文件中每行中的字段的数量

awk -F: '{print NF}' /etc/passwd

                    技术分享图片

                注意:如果语句为print $NF,则会输出每行中最后一个字段

                    技术分享图片

                可以使用print $(NF-1)语句输出每行中倒数第二个字段:

                    技术分享图片


            NR:行的总数;如果仅处理一个文件,可以将NR的值当作此文件中各行的行号;当处理多个文件时,该命令将两个文件的行号累加输出

                示例:输出/etc/fstab文件各行行号

awk '{print NR}' /etc/fstab

                    技术分享图片

    

            

            FNR:对于不同的文件分别统计其行的数量;即使处理多个文件,也可以显示每个文件中每行的行号;

示例:分别输出/etc/fstab和/etc/issue文件的各行行号

awk '{print FNR}' /etc/fstab /etc/issue

                    技术分享图片


            

            FILENAME:当前正在被处理的文件的文件名;

示例:处理/etc/fstab后在最后输出正在处理的文件名:

awk 'END{print FILENAME}' /etc/fstab

                    技术分享图片

                    注:如果在PATTERN部分不添加END,则会输出与文件行数相同行的文件名


            

            ARGC:命令行中参数的数量;包括awk命令本身,但不包括awk命令的选项部分和program部分;

示例:

awk 'END{print ARGC}' /etc/fstab /etc/issue /etc/passwd

                    技术分享图片


            

            ARGV:由命令行中所有的参数构成的数组;

示例:

awk 'END{print ARGV[1]}' /etc/fstab /etc/issue /etc/passwd

    技术分享图片

        
        2)自定义变量

            定义方式:-v var_name=value,注意变量名大小写敏感

            示例:以"USERNAME,hello"格式输出/etc/passwd下记录的所有用户名

awk -v var='hello' -F: '{print $1"," var}' /etc/passwd

                    技术分享图片

    

    2.print动作:以标准格式输出结果

        格式:

            print item1,item2,...

            注意:                

                1) 各item之间需要使用","进行分隔;

2) 输出的各item可以是字符串,可以是数字,可以是当前记录中的字段,可以是变量,可以是awk的表达式;

3) 如果省略了item,则默认的item为$0,即:输出整行;


        示例:输出/etc/issue文档中每行的第1、3和最后一个字段:

            awk '{print $1,$3,$NF}' /etc/issue

                技术分享图片

            输出字符串:

awk 'BEGIN{print "hello world"}'

                技术分享图片


    3.printf动作:以特定的格式输出结果

        格式:           

            printf "FORMAT" item1,item2,...

    注意:

1) 必须给出合适的输出格式;

2) 默认不会自动换行,如果想要在输出结果中换行显示,需要显式给出换行控制符号,即:\n;

3) FORMAT中需要为后面的每一个item单独指定一个格式化符号;


        常用的FORMAT:            

            %c:以ASCII码表中的内容显示字符信息;

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

    %e, %E:以科学计数法来显示数字;浮点类型;

    %f, %F:显示十进制数字的浮点形式;

    %g, %G:以科学计数法显示浮点数字;

    %u:显示无符号十进制数;

    %s:显示字符串;

    %x, %X:显示无符号的十六进制整数;

    %%:显示%;

        修饰符:         

            #[.#]:第一个数字用来控制显示宽度;第二个数字表示小数点的精度;

如:%5s, $8.3f

    -:表示采用左对齐方式显示;默认是右对齐;

    +:显示数字的正负符号;


            示例:以左对齐,宽度20,输出字符串型的用户名,并且以左对齐,宽度,输出整型的UID

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


    4.操作符:       

        1)算术运算操作符:

    双目运算符:

x+y, x-y, x*y, x/y, x^y, x%y

    单目运算符:

-x:将正整数转换为负整数;

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


示例:

awk 'BEGIN{print 100^2}'


        2)字符串操作符:

    无任何操作符号时,即为字符串连接操作;


3)赋值操作符:

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


4)比较操作符:可以放在PATTERN部分作为匹配条件

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

示例:输出UID为1000的行的记录

awk -F : '$3==1000{print $0}' /etc/passwd

              技术分享图片  

        5)模式匹配操作符:

    ~:操作符左侧的字符串是否能够被右侧的PATTERN所匹配;

    !~:操作符左侧的字符串是否不能被右侧的PATTERN所匹配;

示例:输出所有bash为/bin/bash的用户的记录

awk -F : '$NF~/\/bin\/bash/{print $0}' /etc/passwd

           技术分享图片 


        6)逻辑运算操作符:

            &&,||,!

        示例:输出所有UID在1000到9000以内的用户记录

awk -F: '$3>=1000&&$3<=9000{print $0}' /etc/passwd

            技术分享图片


        7)条件表达式:    

            selector(condition)?if-true-expression:if-false-expression

            示例:以"USERNAME:USERTYPE"格式显示/etc/passwd中记录的所有用户,其中UID大于等于1000的USERTYPE为"Common User",UID小于1000的USERTYPE为"SuperUser or Sysuser"

awk -F: '{$3>=1000?usertype="Common User":usertype="SuperUser or Sysuser";print $1","usertype}' /etc/passwd

                技术分享图片


    5.PATTERN部分:        

        1) empty:空模式,不加区分地处理文件的每一行;

2) [!]/REGEXP/:仅处理[不]能被PATTERN匹配到的行;

3) 关系表达式:

4) 行域,行范围:

    ①关系表达式的逻辑运算:FNR>=10&&FNR<==20

                示例:

~]# awk -F: '/^r/,/^a/{print FNR,$0}' /etc/passwd

            技术分享图片

awk 'NR>=1&&NR<=3{print NR,$0}' /etc/passwd

                    技术分享图片

    ②/REGEXP1/,/REGEXP2/: 从被REGEXP1匹配的行开始,直到被REGEXP2匹配的行结束,这期间的所有行,有多少组就显示多少组;

            示例:

                awk -F: '/^r/,/^a/{print NR,$0}' /etc/passwd

                技术分享图片

    5) BEGIN/END模式:

BEGIN{}:仅在开始处理文件中的第一行文本数据之前执行一次的语句块;多用于输出特定格式的表头信息;

END{}:仅在文本处理完成但awk命令尚未退出时执行一次的语句块;多用于数据信息的汇总;

    示例:

awk -F: 'BEGIN{printf "%20s %10s %20s\n","USERNAME","USERID","SHELL"}NR>=15&&NR<=20{printf "%20s %10s %20s\n",$1,$3,$7}END{print "------------------------------------------------------------------\n",NR " users"}' /etc/passwd

                技术分享图片

    注意:

1) BEGIN语句块,PATTERN语句块和END语句块的顺序,通常来讲是:

    BEGIN{}PATTERN{}END{}

2) BEGIN语句块和END语句块是可选的,但PATTERN语句块必须要给出;


    6.控制语句:       

        1) if ... else:

语法:

    if (condition) statement [ else statement ]

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


示例:

    awk -F: '{if($3>=1000){print "CommonUser:",$1}else{print "Sysuser:",$1}}' /etc/passwd

技术分享图片


    df -h | awk -F% '/^\/dev/{print $1}' | awk '{if($NF>=80){print $1}}'


2) while循环:

语法:

while (condition) statement

使用场景:

a.对一行内的多个字段逐一做相同或类似的操作处理时使用;

b.对数组中的各数组元素做遍历处理时使用;


while循环的特点:条件为真,进入循环;一旦条件为假,则退出循环;


示例:

~]# awk '{i=1;while(i<=NF){print $i,length($i);i++}}' testfile


3) do ... while语句:

语法:

do statement while (condition)


意义:与while循环相同,但statement语句段至少被执行一次;


4) for循环:

语法:

for (expr1; expr2; expr3) statement

expr1:variable assignment,变量赋初值;

expr2:circle condition,循环条件判断;

expr3:interation process,变量值修正方法;


示例:

~]# awk '{for(i=1;i<=NF;i++){print $i,length($i)}}' testfile


for (var in array) statement


5) switch ... case语句

语法:

switch (expression) { case value|regex:statement;case value2|regex2:statement;... [ default: statement ] }


使用场景:

用于进行字符串比较判断;


6) break和continue语句:

break [n]

continue


注意:其使用场景是行内多个字段间做循环时的循环控制方式;

示例:

~]# awk '{for(i=1;i<=NF;i++){if(length($i)<5){continue}else{print $i,length($i)}}}' testfile


7) next语句:

在awk处理数据时,提前结束对当前行的处理,而直接开始处理下一行;


示例:

~]# awk -F: '{if($3%2==1){next}else{print $1,$3}}' /etc/passwd

~]# awk -F: '{if($3%2==1)next;print $1,$3}' /etc/passwd


awk工具的使用

标签:linux   awk   文本处理   

原文地址:http://blog.51cto.com/papapa213/2104352

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!