• Awk 实例


    AWK 是一种用于处理文本的编程语言工具。AWK 在很多方面类似于 shell 编程语言,尽管 AWK 具有完全属于其本身的语法。它的设计思想来源于 SNOBOL4 、sed 、Marc Rochkind设计的有效性语言、语言工具 yacc 和 lex ,当然还从 C 语言中获取了一些优秀的思想。在最初创造 AWK 时,其目的是用于文本处理,并且这种语言的基础是,只要在输入数据中有模式匹配,就执行一系列指令。该实用工具扫描文件中的每一行,查找与命令行中所给定内容相匹配的模式。如果发现匹配内容,则进行下一个编程步骤。如果找不到匹配内容,则继续处理下一行。
    尽管操作可能会很复杂,但命令的语法始终是:
    awk '{pattern + action}' 或者 awk 'pattern {action}'
    其中 pattern 表示 AWK 在数据中查找的内容,而 action 是在找到匹配内容时所执行的一系列命令。花括号 ({}) 不需要在程序中始终出现,但它们用于根据特定的模式对一系列指令进行分组。

    内置变量介绍

    awk提供了有很多内置变量,如果你经常使用awk处理文本,了解这些这些内置变量的使用是很有必要的。下面看一下这些内置变量的详细介绍。
    ARGC命令行参数个数(不包括awk的选项和awk的程序内容)。
    ARGIND 当前正在处理的ARGV中的文件的索引值(同时处理多个文件时会用到)。
    ARGV 命令行参数序列数组,下标从0开始。
    CONVFMT 数字转换格式,和C语言中的数字输出格式化类似,默认为"%.6g"。
    ENVIRON 当前系统的环境变量。
    ERRNO 出错时的错误信息。
    FIELDWIDTHS 以空格分隔的字段宽度,如果指定此变量,awk将会用指定的宽度替换变量FS指定的分隔符。看下面的例子:
    [LinuxSong@test /tmp]$ cat t
    abcdefasfa
    abcdefasfa
    abcdefasfa
    [LinuxSong@test /tmp]$ awk 'BEGIN {FIELDWIDTHS="2 3 4"}{print $1,$2,$3}' t
    ab cde fasf
    ab cde fasf
    ab cde fasf
    FILENAME 当前正在处理的文件名,该变量不能在BEGIN块中使用。
    FNR当前处理的记录号。
    FS 字段的分隔符,默认为空格。
    IGNORECASE 如果该变量设置为非0值,在进行字符串匹配时忽略大小写。
    NF 当前记录中的字段个数。
    NR 已经读出的记录数。
    OFMT 数字的输出格式。
    OFS 输出的字段分隔符,默认为空格。
    ORS 输出的记录分隔符,默认为新行。
    RS 输入记录的分隔符,默认为新行。
    RSTART 被match()函数匹配的字符串的起始位置,如果没有匹配则为0(从1开始)。
    RLENGTH 被match()函数匹配的字符串的长度。
    SUBSEP数组中多个下标的分隔符,默认为"34"。

    内置函数

    awk 之所以成为一种优秀的程序设计语言的原因之一是它吸收了某些优秀的程序设计语言(例如C)语言的许多优点。这些优点之一就是内置函数的使用,awk定义并支持了一系列的内置函数,由于这些函数的使用,使得awk提供的功能更为完善和强大,例如,awk使用了一系列的字符串处理内置函数(这些函数看起来与C 语言的字符串处理函数相似,其使用方式与C语言中的函数也相差无几),正是由于这些内置函数的使用,使awk处理字符串的功能更加强大。本文后面的附录中列有一般的awk所提供的内置函数,这些内置函数也许与你的awk版本有些出入,因此,在使用之前,最好参考一下你的系统中的联机帮助。
    内置的字符串函数

    gsub(r,s)
    在整个$0中用s代替r
    gsub(r,s,t)
    在整个t中用s替代r
    index(s,t)
    返回s中字符串t的第一位置
    length(s)
    返回s长度
    match(s,r)
    测试s是否包含匹配r的字符串
    split(s,a,fs)
    在fs上将s分成序列a
    sprint(fmt,exp)
    返回经fmt格式化后的exp
    sub(r,s)
    用$0中最左边最长的子串代替s
    substr(s,p)
    返回字符串s中从p开始的后缀部分
    substr(s,p,n)
    返回字符串s中从p开始长度为n的后缀部分 

    Awk 实例

    awk 用法:awk ' pattern {action} ' 
    转自:http://bbs.chinaunix.net/viewthread.php?tid=691456
    变量名                含义
    ARGC                命令行变元个数
    ARGV                命令行变元数组
    FILENAME        当前输入文件名
    FNR                当前文件中的记录号
    FS                输入域分隔符,默认为一个空格
    RS                输入记录分隔符
    NF                当前记录里域个数
    NR                到目前为止记录数
    OFS                输出域分隔符
    ORS                输出记录分隔符
    
    1、awk '/101/'               file 显示文件file中包含101的匹配行。
       awk '/101/,/105/'         file
       awk '$1 == 5'             file
       awk '$1 == "CT"'          file 注意必须带双引号
       awk '$1 * $2 >100 '       file 
       awk '$2 >5 && $2<=15'     file
    2、awk '{print NR,NF,$1,$NF,}' file 显示文件file的当前记录号、域数和每一行的第一个和最后一个域。
       awk '/101/ {print $1,$2 + 10}' file 显示文件file的匹配行的第一、二个域加10。
       awk '/101/ {print $1$2}'  file
       awk '/101/ {print $1 $2}' file 显示文件file的匹配行的第一、二个域,但显示时域中间没有分隔符。
    3、df | awk '$4>1000000 '         通过管道符获得输入,如:显示第4个域满足条件的行。
    4、awk -F "|" '{print $1}'   file 按照新的分隔符“|”进行操作。
       awk  'BEGIN { FS="[: 	|]" }
       {print $1,$2,$3}'              file 通过设置输入分隔符(FS="[: 	|]")修改输入分隔符。
    
       Sep="|"
       awk -F $Sep '{print $1}'  file 按照环境变量Sep的值做为分隔符。   
       awk -F '[ :	|]' '{print $1}' file 按照正则表达式的值做为分隔符,这里代表空格、:、TAB、|同时做为分隔符。
       awk -F '[][]'    '{print $1}' file 按照正则表达式的值做为分隔符,这里代表[、]
    5、awk -f awkfile              file 通过文件awkfile的内容依次进行控制。
       cat awkfile
    /101/{print "47 Hello! 47"} --遇到匹配行以后打印 ' Hello! '.47代表单引号。
    {print $1,$2}                   --因为没有模式控制,打印每一行的前两个域。
    6、awk '$1 ~ /101/ {print $1}' file 显示文件中第一个域匹配101的行(记录)。
    7、awk   'BEGIN { OFS="%"}
       {print $1,$2}'           file 通过设置输出分隔符(OFS="%")修改输出格式。
    8、awk   'BEGIN { max=100 ;print "max=" max}             BEGIN 表示在处理任意行之前进行的操作。
       {max=($1 >max ?$1:max); print $1,"Now max is "max}' file 取得文件第一个域的最大值。
       (表达式1?表达式2:表达式3 相当于:
       if (表达式1)
           表达式2
       else
           表达式3
       awk '{print ($1>4 ? "high "$1: "low "$1)}' file 
    9、awk '$1 * $2 >100 {print $1}' file 显示文件中第一个域匹配101的行(记录)。
    10、awk '{$1 == 'Chi' {$3 = 'China'; print}' file 找到匹配行后先将第3个域替换后再显示该行(记录)。
        awk '{$7 %= 3; print $7}'  file 将第7域被3除,并将余数赋给第7域再打印。
    11、awk '/tom/ {wage=$2+$3; printf wage}' file 找到匹配行后为变量wage赋值并打印该变量。
    12、awk '/tom/ {count++;} 
             END {print "tom was found "count" times"}' file END表示在所有输入行处理完后进行处理。
    13、awk 'gsub(/$/,"");gsub(/,/,""); cost+=$4;
             END {print "The total is $" cost>"filename"}'    file gsub函数用空串替换$和,再将结果输出到filename中。
        1 2 3 $1,200.00
        1 2 3 $2,300.00
        1 2 3 $4,000.00
    
        awk '{gsub(/$/,"");gsub(/,/,"");
        if ($4>1000&&$4<2000) c1+=$4;
        else if ($4>2000&&$4<3000) c2+=$4;
        else if ($4>3000&&$4<4000) c3+=$4;
        else c4+=$4; }
        END {printf  "c1=[%d];c2=[%d];c3=[%d];c4=[%d]
    ",c1,c2,c3,c4}"' file
        通过if和else if完成条件语句
    
        awk '{gsub(/$/,"");gsub(/,/,"");
        if ($4>3000&&$4<4000) exit;
        else c4+=$4; }
        END {printf  "c1=[%d];c2=[%d];c3=[%d];c4=[%d]
    ",c1,c2,c3,c4}"' file
        通过exit在某条件时退出,但是仍执行END操作。
        awk '{gsub(/$/,"");gsub(/,/,"");
        if ($4>3000) next;
        else c4+=$4; }
        END {printf  "c4=[%d]
    ",c4}"' file
        通过next在某条件时跳过该行,对下一行执行操作。
    
    
    14、awk '{ print FILENAME,$0 }' file1 file2 file3>fileall 把file1、file2、file3的文件内容全部写到fileall中,格式为
        打印文件并前置文件名。
    15、awk ' $1!=previous { close(previous); previous=$1 }   
        {print substr($0,index($0," ") +1)>$1}' fileall 把合并后的文件重新分拆为3个文件。并与原文件一致。
    16、awk 'BEGIN {"date"|getline d; print d}'         通过管道把date的执行结果送给getline,并赋给变量d,然后打印。 
    17、awk 'BEGIN {system("echo "Input your name:\c""); getline d;print "
    Your name is",d,"!
    "}'
        通过getline命令交互输入name,并显示出来。
        awk 'BEGIN {FS=":"; while(getline< "/etc/passwd" >0) { if($1~"050[0-9]_") print $1}}'
        打印/etc/passwd文件中用户名包含050x_的用户名。
    
    18、awk '{ i=1;while(i<NF) {print NF,$i;i++}}' file 通过while语句实现循环。
        awk '{ for(i=1;i<NF;i++) {print NF,$i}}'   file 通过for语句实现循环。    
        type file|awk -F "/" '
        { for(i=1;i<NF;i++)
        { if(i==NF-1) { printf "%s",$i }
        else { printf "%s/",$i } }}'               显示一个文件的全路径。
        用for和if显示日期
        awk  'BEGIN {
    for(j=1;j<=12;j++)
    { flag=0;
      printf "
    %d月份
    ",j;
            for(i=1;i<=31;i++)
            {
            if (j==2&&i>28) flag=1;
            if ((j==4||j==6||j==9||j==11)&&i>30) flag=1;
            if (flag==0) {printf "%02d%02d ",j,i}
            }
    }
    }'
    19、在awk中调用系统变量必须用单引号,如果是双引号,则表示字符串
    Flag=abcd
    awk '{print '$Flag'}'   结果为abcd
    awk '{print  "$Flag"}'   结果为$Flag
    每天一小步,人生一大步!Good luck~
  • 相关阅读:
    安卓反编译
    Icesugar Gourd
    php文件写入
    java 序列化与反序列化
    Toj Dominoes Game
    adb&frida
    Markdown 测试用例
    iview InputNumber类输入框表单验证失效
    01背包问题(回溯算法实现)
    阅读作业二读Lost in CatB有感 by 李栋
  • 原文地址:https://www.cnblogs.com/jkmiao/p/4864370.html
Copyright © 2020-2023  润新知