• AWK整理


    处理模式:

    awk的处理文本和数据的方式是这样的,它逐行扫描文件,从第一行到最后一行,寻找匹配的特定模式的行,并在这些行上进行你想要的操作。如果没有指定处理动作,则把匹配的行显示到标准输出(屏幕),如果没有指定模式,则所有被操作所指定的行都被处理。

    组成部分:

    处理输入前将做的处理BEGIN,

    处理输入过程将做的处理,

    处理输出完成后做的处理END

    指定分隔符:

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

    awk -F:  '{print $1}' /etc/passwd

    echo "hello:world.yes/no"| awk 'BEGIN { FS = "[:/.]" }  {print $1, $2, $3 }'

    #按照正则表达式的值做为分隔符,这里代表空格、: / .同时做为分隔符

    awk的赋值:

    无需声明,直接定义赋值,而且运算都很通常

    实例:

    统计空行数

    awk '/^$/ { x++} END{print x}' test

           计算平均值:

    awk '{avg=($2+$3+$4)/3} {print $1 " " avg}' grade

    awk中的系统变量:

     NF:当前输出记录的字段个数,$NF 常用于表示最后一字段

    NR: 记录当前的处理的行号
    ARGC   命令行变元个数 
    ARGV   命令行变元数组 
    FILENAME   当前输入文件名 
    FNR   当前文件中的记录号 
    FS   输入域分隔符,默认为一个空格 
    RS   输入记录分隔符 一般是个换行符
    OFS   输出域分隔符 
    ORS   输出记录分隔符 

    实例:算账:

    数据:

    1000

    125  market     -125

    126  a       -19

    128  vc     -20

    程序:

    awk '

    BEGIN {FS = " "}

    NR == 1 { print "Begin : " $1

            balance = $1

            next}

    {

    print $1,$2,$3

    print balance += $3

    } ' grade

    结果

    Begin :      1000

    125 market -125

    875

    126 a -19

    856

    128 vc -20

    836

    awk中的匹配:

    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

    df | awk '$4>1000000 '              #通过管道符获得输入,如:显示第4个域满足条件的行。

     awk '$1 !~ /101/ {print $1}' file         不显示显示文件中第一个域匹配101的行(记录)

    awk '/^(redis|mysql)/' passwd                   开头以redis或者mysql开头的行

    awk '/^[rm]/' passwd                                  开头以r或者m开头

    awk –FS:'$1 ~ /t$/' passwd                      第一个字段以t结尾的

    awk '/tom/ {count++;}  
             END {print "tom was found "count" times"}' file            计算字段出现次数

    awk '/^root/,/^mysql/' test        打印以root开头的记录到以mysql开头的记录范围内的所有记录。如果找到一个新的正则表达式root开头的记录,则继续打印直到下一个以正则表达式mysql开头的记录为止,或到文件末尾。

    AWK的格式化输出:和c语言一样

    printf(”%-15s %10d ”, $9, $5)

    例子:如何把一行竖排的数据转换成横排?

    awk '{printf("%s,",$1)}' filename

    AWK中的判断和逻辑运算:

    运算符

    描述

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

    赋值

    ?:

    C条件表达式

    ||

    逻辑或

    &&

    逻辑与

    ~ !~

    匹配正则表达式和不匹配正则表达式

    < <= > >= != ==

    关系运算符

    空格

    连接

    + -

    加,减

    * / &

    乘,除与求余

    + - !

    一元加,减和逻辑非

    ^ ***

    求幂

    ++ --

    增加或减少,作为前缀或后缀

    $

    字段引用

    in

    数组成员

    AWK中的条件

    语法:如果条件非零非空则为真,执行action1,

    if(expression){

           action1

           action1.1

    else

           action2

    例子: 

    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 

    三目运算符:

           expr ? “Success_action1”: fail_action

    awk   'BEGIN { max=100 ;print "max=" max}             

    #BEGIN 表示在处理任意行之前进行的操作。 
            {max=($1 >max ?$1:max); print $1,"Now max is "max}' file          

    #取得文件第一个域的最大值。

    awk输出结果到文件:

    写入>

    awk '{ print FILENAME,$0 }' file1 file2 file3>fileall     

    把file1、file2、file3的文件内容全部写到fileall中,格式为打印文件并前置文件名。

    恢复时,把合并后的文件重新分拆为3个文件。并与原文件一致

    awk ' $1!=previous { close(previous); previous=$1 }    
        {print substr($0,index($0," ") +1)>$1}' fileall          

    如果当前$1(文件名)不等于先前的,就是新的文件了,那么文件名$1就要改变

    index,找出字段的位置,由于文件名和字段$0是以一个空格分开的。

    substr找出特定的子串,就是文件名之后的所有字段

    拼接文件:

    现在有两个文件格式如下:

    #cat account
    张三|000001
    李四|000002
    #cat cdr
    000001|10
    000001|20
    000002|30
    000002|15

    想要得到的结果是将用户名,帐号和金额在同一行打印出来,如下:

    张三|000001|10
    张三|000001|20
    李四|000002|30
    李四|000002|15

    awk -F| 'NR==FNR {a[$2]=$0; next}{print a[$1]" | "$2}' account adr

    因为在第一个文件区域时,NR和NFR是相等的所以把第一个文件整个字段缓存到a数组中去

    awk中的循环:

    break 跳出本层循环,continue结束本次循环;

    exit在某条件时退出,但是仍执行END操作。 

    next在某条件时跳过该行,对下一行执行操作

    while (condition){

             actions

    }

    do循环:至少执行一次

    do    

    action

    while(condition)

    for循环:

    for(set_counter; test_counter; increment_index)

    action

    例子:

    awk '{ i=1;while(i<NF) {print NF,$i;i++}}' file       通过while语句实现循环。 
           awk '{ for(i=1;i<NF;i++) {print NF,$i}}'   file        通过for语句实现循环。 

    awk中的数组:

    和c语言一样,不用声明

    关联数组:下标可以是字符串和数值

    访问关联数组:

           for (item in array)

                  print item, array[item]

    awk中的函数:

    算术函数:

    cos(x)余弦、exp(x)e的x次幂、int(x)整数部分

    sin(x)正弦、log(x)e的x对数、sqrt(x)平方根

    rand()随机数、srand(x),建立新种子、默认时当天时间

    字符串函数:

    gsub(r,s,t) r正则表达式匹配,s将被替换字符串,t替换字符串

    例子:awk 'gsub(/$/,"");gsub(/,/,""); cost+=$4; 
             END {print "The total is $" cost>"filename"}'    file            

    #用空串替换$和,再将结果输出到filename中。 

    sub(r,s,t)首次出现

    substr(s,p,n)当指定n时,返回s[p]~s[p+n]的字符串,没制定就是s[p]-

    index(s,t)t字符在s的位置

    length(s) s的长度

    split 函数可按给定的分隔符把字符串分割为一个数组。如果分隔符没提供,则按当前FS值进行分割

                    awk 'BEGIN{ split("2015-12-30",time, "-");print time[1]}'

    match(s,r)r正则表达式,返回出现r的起始位置

    awk '{start=match("this is a test",/[a-z]+$/); print start}'

    awk '{start=match("this is a test",/[a-z]+$/); print start, RSTART, RLENGTH }'

    第一个实例打印以连续小写字符结尾的开始位置,这里是11。

    第二个实例还打印RSTART和RLENGTH变量,这里是11(start),11(RSTART),4(RLENGTH)

    tolower()  小写

    toupper() 大写

    awk 'BEGIN{print toupper("test")}'

    systime()当前时间戳

       strftime函数使用C库中的strftime函数格式化时间。格式如下:

    systime( [format specification][,timestamp] )

    awk 'BEGIN{print strftime("%m-%d-%y",systime())}'

    awk 'BEGIN{print strftime("%F",systime())}'

    getline 从输入中读取另一行,既能读取正常的输入数据,又能处理来自文件和管道的输入

                  成功读取返回1,文件结尾返回0,文件错误返回-1

           从文件读取 while ((getline < “data”) > 0)

                                       print

    从标准输入读取:

    awk 'BEGIN {printf "enter name:"; getline name  < "-" ;print name}'

    管道符:

    awk 'BEGIN {"date"| getline name  < "-" ;print name}'

    例子读取当前用户在/etc/passwd的字段:(实际只有root可以~_~)

    awk 'BEGIN{"who am i"| getline ; name=$1; FS =":"} name ~ $1  {print $0}' /etc/passwd

    close():关闭打开的文件和管道,这样有的命令可以复用多次

    system():执行命令(阻塞式),返回被执行的命令的退出状态

           例子:awk 'BEGIN {if (system("ls") != 0) print "Failed"; else print "ok" }'

     
    参考博文: http://www.cnblogs.com/emanlee/p/3327576.html
  • 相关阅读:
    express学习
    安装MongoDB步骤
    js事件流
    关于html,css,js三者的加载顺序问题
    重写JS的鼠标右键点击菜单
    深入JS原型与原型链
    eureka学习(二)
    eureka学习(一)
    mysql学习-explain中的extra
    mysql学习-explain
  • 原文地址:https://www.cnblogs.com/wxl-dede/p/5003709.html
Copyright © 2020-2023  润新知