• awk命令简单实用


    把要分析的文件放到cywin 目录"home/{当前登录用户名}/" 下,这个好像是可以配置。

    分析日志的页面访问,按次数排序,次数多的在最后

    awk '{print $4}' click.log | sort | uniq -c| sort -n

    所有文件被访问的次数.

    awk '{print $7}' access_log|sort |uniq -c|sort -nr
    所有访问源IP的链接次数.

    awk '{print $1}' access_log | sort |uniq -c |sort -nr
    cat access_log.2007-01-19.log | awk -F" " '{print $1}' | sort |uniq -c  | sort -rn
    awk -F" " '{print $1}'  #用空格分隔,打印第一列数据
    sort|uniq -c # 排序并过滤重复,-c 输出重复次数
    sort –rn # 按-n数字进行-r反向排序

     ----------------以下没实验过-可参考---------------------------------------------------------

    ----------------------------------------------------------------------------------------------------

    详细介绍,copy来源地址:http://blog.163.com/forest-1980/blog/static/97402162007111264819218/

    AWK介绍
    9.1    调用awk
    三种方式:
    1.    命令行方式:    
    awk [-F filed-separator] 'commands' input-files
    -F    指定分隔符(默认是空格或tab)
    commands    awk的命令
    input-files    要处理的文件
    2.    将所有awk命令插入一个文件,并使awk程序可执行,然后用awk命令解释器作为脚本的首行,以便通过键入脚本名称来调用它
    3.    将所有的awk命令插入一个单独文件,然后调用:
    awk -f awk-script-file input-files
    -f    指明调用脚本名
    input-files    待处理的文件

    9.2    awk脚本
    在命令中调用awk时,awk脚 本由各种操作和模式组成。
    awk每次读一条记录或一行,并使用指定的分隔符分隔指定域。当新行出现时,awk命令获悉已读完整条记录,然后在下一 个记录启动读命令,这个读进程将持续到文件尾或文件不再存在。
    9.2.1    模式和动作
    任何awk语句都由模式和动作组成。模式部分 决定动作语句何时触发及触发条件。处理即对数据进行的操作。如果省略模式部分,动作将时刻保持执行状态。
    模式可以是任何条件语句、复合语句或正则 表达式,包括两个特殊字段BEGIN和END。使用BEGIN语句设置计数和打印头。BEGIN语句用在任何文本浏览动作之前,之后文本浏览动作依据输入 文件开始执行。END语句用在awk完成文本浏览动作后打印输出文本总数和结尾状态标志。如果不特别指明模式,awk总是匹配。
    实际动作在大括号 {}内指明。动作大多数用来打印,但还有些更长的代码诸如if和循环语句及循环退出结构。如果不指明采取动作,awk将打印出所有浏览出来的记录。
    9.2.2    域和记录
    awk执行时,其浏览域标记为$1,$2…$n,这种方法称为域标识。当需要指定多域时使用逗号,用于分隔,如$1,$3指定第一域 和第三域,如果希望指定所有域可使用$0。
    使用print命令执行打印操作,这是一个awk命令,需要用{}括起来。
    1.    抽取域
    举 例: 现有一个grade.txt文件,内容如下:
    $ cat grade.txt
    M.Tansley        05/99    48311    Green    8    40    44
    J.Lulu            06/99    48317    Green    9    24    26
    P.Bunny        02/99    48        Yellow    12    35    28
    J.Troll            07/99    4842    Brown-3    12    26    26
    L.Tansley        05/99    4712    Brwon-2    12    30    28
    此 文本文件有7个域,以空格作为域分隔符
    2.    保存awk输出
    两种方式保存awk的输出结果:
    重定向到文件:(屏幕无显示)
    $ awk '{print $0}' grade.txt >wow
    使用管道将输出结果传给tee:(屏幕显示结果)
    $ awk '{print $0}' grade.txt|tee woww
    3.    使用标准输入
    几种方法:
    $ belts.awk grade.txt
    $ belts.awk < grade.txt
    4.    打印所有记录
    $ awk '{print $0}' grade.txt
    5.    打印单独记录
    只打印$1和$4:
    $ awk '{print $1,$4}' grade.txt
    6.    自定义格式打印
    可以在$1和$4的上方添加注释,Name和Belt:
    $ awk 'BEGIN {print "Name\t\tBelt\n-------------------------"} {print $1"\t"$4}' grade.txt
    在结尾加上结束注释:
    $ awk 'BEGIN {print "Name\t\tBelt\n-------------------------"} {print $1"\t"$4} END {print "-------------------------\nEnd of report"}' grade.txt
    7.    awk错误信息提示
    在碰到awk错误时,可相应查找:
    •    确保整个awk命令用单引号括起来
    •    确保命令内所有引号成对出现
    •    确保用大括号{}括起动作语句,用括号()括起条件语句
    •    可能忘记使用大括号{}
    8.    awk键盘输入
    如果没有给出输入文件,awk从键盘获得输入,完成后按<Ctrl-D>结束输入
    9.2.3    元字符
    \ ^ $ . [ ] | ( ) * + ?
    其中+和?只适用于awk而不适用于grep或sed:
    +    匹配一个或一个以上前面的单字符
    ?    匹配0个或一个前面的单字符
    举例:
    /XY+Z/    匹配XYZ、XYYYYZ
    /XY?Z/    匹配XYZ、XZ
    9.2.4    条件操作符
    操作符            描述
      <                小于
      <=              小于等于
      ==                等于
      !=               不等于
      >                大于
      >=              大于等于
      ~           匹配正则表达式
      !~          不匹配正则表达式
    1.    匹配
    使 用~紧跟正则表达式可以匹配域,也可以用if,条件需要用()括起来
    举例:
    查询棕带学员的所有情况(打印出$4匹配Brown的行)
    $ awk '{if ($4~/Brown/) print $0}' grade.txt

    $ awk '$0 ~ /Brown/' grade.txt
    2.    精确匹配
    使用==并用双引号括起条件可以精确匹配条件
    举例:
    $ awk '{if ($3 == "48") print $0}' grade.txt
    3.    不匹配
    使用!~紧跟正则表达式不匹配域
    举例:
    查 询不是棕带的所有学员情况(打印出$4不匹配Brown的行)
    $ awk '{if ($4!~/Brown/) print $0}' grade.txt

    $ awk '$0 !~ /Brown/' grade.txt
    4.    比较
    由于几个比较大 小符的使用方法都一样,就随便举一个例子:
    $ awk '{if ($6 < $7) print $1" try better at the next comp"}' grade.txt
    5.    各种匹配
    匹配Green或green:
    $ awk '/[Gg]reen/' grade.txt
    匹配$1的第四个字符是a:
    $ awk '$1 ~ /^...a/' grade.txt
    匹配Yellow或Brown:
    $ awk '$4 ~ /Yellow|Brown/' grade.txt
    匹 配以J开头的行:
    $ awk '$0 ~ /^J/' grade.txt
    6.    复合表达式
    复合模式或复合操作符用于形成 复杂的逻辑操作,复合表达式即为模式间通过使用复合操作符互相结合起来的表达式
    &&    AND:    符号两边必须同时为真
    || OR:    符号两边至少一边为真
    ! :    非 求逆
    举例:
    $ awk '{if ($1 == "P.Bunny" && $4 == "Yellow") print $0}' grade.txt
    $ awk '{if ($4 == "Yellow" || $4 ~ /Brown/) print $0}' grade.txt
    9.2.5    awk内置变量
    awk有许多内置变量用来设置环境信息,常用的有:
    ARGC        命令行参数个数
    ARGV        命令行参数排列
    ENVIRON        支持队列中系统环境变量的使用
    FILENAME    awk读取的文件名
    FNR            当前文件已处理的记录行数
    FS            设置域分隔符,相当于-F
    NF            域的列数
    NR            已处理的记录总行数
    OFS            设置输出字段域分隔符
    RS/ORS        换行符

    ARGC支持命令行中传入awk脚本的参数个数。ARGV是ARGC的参数排列数组,其中每一元素表示为 ARGV[n],n为希望访问的命令行参数
    ENVIRON支持系统设置的环境变量,要访问单独变量,使用实际变量名,如 ENVIRON[“EDITOR”]=”Vi”
    FILENAME为awk脚本当前操作文件的文件名
    FNR为awk当前操作文件的记录行 数,其值总是小于等于NR。如果脚本正在访问多个文件,每一新输入文件都将重置此变量
    FS用来设置域分隔符,与命令行中-F相同,缺省为空格。 如: 以冒号为分隔符FS=":"
    NF为记录域个数(列数),在记录被读之后设置,常用$NF指定最后一列
    OFS指定输出记录的域分隔 符,缺省为空格。如: 以-为分隔符输出FS="-"
    ORS与RS都为输出记录分隔符,缺省是新行(\n)
    举例:
    查看文件的记录 数:
    $ awk 'END {print NR}' grade.txt
    打印所有记录及记录的行号及总域数,并在最后打印出读取文件的文 件名:
    $ awk '{print NF,NR,$0} END {print FILENAME}' grade.txt
    至少包含一个 记录且包含Brown:
    $ awk '{if (NR > 0 && $4 ~ /Brown/) print $0}' grade.txt
    NF的一个强大功能是将变量$PWD的返回值传入awk并显示其目录:
    $ echo $PWD | awk -F/ '{print $NF}'
    显示文件名:
    $ echo "/usr/apache/conf/httpd.conf" | awk -F/ '{print $NF}'
    9.2.6    awk操作符
    awk操作符的基本表达式可以划分为数字型、字符串型、变量型域及数 组元素
    = += -= *= /= %= ^=            赋值操作符
    ?                        条件表达操作符
    || && !                    并、与、非
    ~ !~                        匹配操作符(匹配与不匹配)
    < <= == != > >=                关系操作符
    + - * / % ^                算术操作符
    ++ --                        前缀和后缀
    1.    设置输入域到域变量名
    在awk中,设置有意义的域名是一种好习惯,在进行模式匹配或关系操作时更容易理 解。一般的变量名设置方式为name=$n,这里name为调用的域变量名,n为实际域号。多个域名设置之间用分号;分隔(请注意下面;的使用)
    $ awk '{name = $1;belts = $4; if (belts ~ /Yellow/) print name" is belt "belts}' grade.txt
    2.    域值比较操作
    有两种方式测试一数值域是否小于另一数值域:
    1)    在BEGIN中给变量名赋值
    2)    在关系操作符中使用实际数值
    通常在BEGIN部分赋值是很有益的,可以在awk表达式进行改动 时减少很多麻烦。使用关系操作时必须用圆括号括起来。举例:
    查询所有比赛中得分在27点一下的学生:
    $ awk '{if ($6 < 27) print $0}' grade.txt

    $ awk 'BEGIN {BASELINE = "27"} {if ($6 < BASELINE) print $0}' grade.txt
    3.    修改数值域取值
    当在awk中修改任何域 时,重要的一点是要记住实际输入文件是不可修改的,修改的只是保存在缓存里的awk复本。awk会在变量NR或NF中反映出修改痕迹
    为修改数值 域,简单的给域标识重赋新值。举例:
    $ awk '{if ($1 == "M.Tansley") $6 = $6 - 1; print $1,$6,$7}' grade.txt
    4.    修改文本域
    修改文本域即对其重新赋值,赋给一个新的字符串。记住,字符串要使用双 引号,并用圆括号括起整个语法。举例:
    $ awk '{if ($1 == "J.Troll") ($1 = "J.L.Troll"); print $1}' grade.txt
    5.    只显示修改记录
    如果文件很大,修改的记录很多,所以需要只查看修改部分。在模式后 面使用大括号{}将只打印修改部分。取得模式,再根据模式结果实施操作。举例:(注意大括号的位置)
    $ awk '{if ($1 == "J.Troll") {$1 = "J.L.Troll"; print $1}}' grade.txt
    6.    创建新的输出域
    在 awk中处理数据时,基于各域进行计算时创建新域是一种好习惯。创建新域要通过其他域赋予新域标识符。举例:
    在grade.txt中创建新域8保 存域目前级别分与域最高级别分的差值:
    $ awk 'BEGIN {print "Name\tDifference"} {if ($6 < $7) {$8 = $7 - $6; print $1,$8}}' grade.txt
    或者赋予便于理解的变量名:
    $ awk 'BEGIN {print "Name\tDifference"} {if ($6 < $7) {diff = $7 - $6; print $1,diff}}' grade.txt
    7.    增加列值
    使用符号+=增加列数或进行运行结果统计。将符号右边的变量 域的值赋给左边。
    举例:
    打印出所有学生的总成绩(将整个文件的$6求和,total为变量名):
    $ awk '(total += $6); END {print "Club student total points: "total}' grade.txt
    如果文 件很大,只想打印结果部分而不是所有记录,在语句的外面加上大括号{}即可:
    $ awk '{(total += $6)}; END {print "Club student total points: "total}' grade.txt
    查看当前目录所有文件大小及总和 (除去子目录):
    $ ls -l|awk '/^[^d]/ {print $9"\t"$5} {total += $5} END {print "total Bytes: "total}'
    9.2.9    内置的字符串函数
    awk有很多强大的字符串函数:
    gsub(r,s,t)                在整个字符串t中用字符串s替代所有满足正则表达式r的字符串(如没指定t则默认为$0)
    index(s,t)                返回字符串s中字符串t第一次出现的位置(如不存在则为0)
    length(s)                返回s字符串的长度(如没指定s则默认为$0)
    match(s,r)            返回第一个满足正则表达式r的字符串在s字符串里面的位置(如无匹配的则为0)
    split(s,a,sep)            使用sep将字符串s分隔成为数组a的元素,返回数组元素的数量(如果没指定分隔符则默认与FS相同用法)
    sprint("fmt",exp)        使用printf的格式说明对表达式exp 进行格式化输出
    sub(r,s,t)                在字符串t中用s字符串替换满足正则表达式r的第一个字符串,返回1如果成功,否则返回0(如没指定t则默认为$0)
    substr(s,p,n)            返回字符串s中以p位置开始长度为n的字符串(如果没指定n则返回从p位置开始的所有字符串)
    tolower(s)            将字符串s中的所有大写字母转换为小写,返回转换后的字符串
    toupper(s)            将字符串s中的所有小写字母转换为大写,返回转换后的字符串
    1.    gsub(r,s,t)
    在整个字符串t中用字符串s替代所有满 足正则表达式r的字符串(如没指定t则默认为$0):
    $ awk 'gsub(/4842/,4899) {print $0}' grade.txt

    $ awk '{if (gsub(/4842/,4899)) print $0}' grade.txt
    2.    index(s,t)
    返回字符串s中字符串t第一次出现的位置(如不存在则为0)。必须用双引号将字符串都括起来:
    $ awk 'BEGIN {print index("Benny","ny")}' grade.txt
    3.    length(s)
    返回s字 符串的长度(如没指定s则默认为$0):
    $ awk '$1 == "J.Troll" {print length($1)" "$1}' grade.txt
    $ awk 'BEGIN {print length("Kevin is a good boy.")}'
    4.    match(s,r)
    返回第一个满足正则表达式r的字符串在s字符串里面的位置:
    $ awk 'BEGIN {print match("ANCD",/d/)}'(返回0)
    $ awk '$1=="J.Lulu" {print match($1,/u/)}' grade.txt(返回第一个u在J.Lulu里的位置: 3)
    5.    split(s,a,sep)
    使用sep将字符串s分隔成 为数组a的元素,返回数组元素的数量:
    $ awk 'BEGIN {print split("123#456#789",array,"#")}'
    返回3,数组array的元素分别为:
    array[1]="123"
    array[2]="456"
    array[3]="789"
    6.    sub(r,s,t)
    在字符串t中用s字符串替换满足正则表达式r的第一个字符串,返回1如果成功,否则返回0(如没指定t则默认为$0):
    $ awk '$1 == "J.Troll" {if (sub(/26/,"29")) print}' grade.txt
    7.    substr(s,p,n)
    返回字符串s中以p位置开始长度为n的字符串(如果没指定n则返回从p位置开始的所有字符串):
    $ awk '$1 == "L.Tansley" {print substr($1,1,5)}' grade.txt(返回L.Tan)
    如果给定长度 值n大于字符串长度,则awk将从起始位置返回所有字符:
    $ awk '$1 == "L.Tansley" {print substr($1,3,15)}' grade.txt(返回Tansley)
    如果没指定n,则awk将从起始位置返回所有字符:
    $ awk '{print substr($1,3)}' grade.txt
    在BEGIN部分定义字符串,在END部分返回抽取的字符:
    $ awk 'BEGIN {STR="Kevin is a good boy."} END {print substr(STR,12,8)}' grade.txt
    8.    从shell中向awk传入字符串
    $ echo "Stand-by"|awk '{print length($0)}'
    设置文件名为一变量,取文件名:
    $ STR="grade.txt"
    $ echo $STR|awk '{print substr($STR,1,5)}'
    取文件名后缀:
    $ STR="grade.txt"
    $ echo $STR|awk '{print substr($STR,7) }'
    9.2.10    awk输出函数printf
    awk提供函数 printf,拥有几种不同的格式化输出功能。每一种printf函数(控制格式字符)都以一个%符号开始,以一个决定转换的字符结束。转换包含三种修饰 符。
    语法:
    printf "格式控制符",参数

    awk printf修饰符
    -        左对齐
    Width    域的步长,用0表示0步长
    .prec    最大字符串长度,或小数点右边的位数

    awk printf格式
    %c        ASCII字符
    %d        整数
    %e        浮点数(科学记数法)
    %f        浮点数
    %g        awk决定使用哪种浮点数转换(e或者f)
    %o        八进制数
    %s        字符串
    %x        十六进制数
    举例:
    字符转换:
    $ awk 'BEGIN {printf "%c\n",65}' grade.txt
    格 式化输出:
    打印所有的学生名字和序列号,要求名字左对齐,15个字符长度,后跟序列号:
    $ awk '{printf "%-15s %s\n",$1,$3}' grade.txt
    再加入注释:
    $ awk 'BEGIN {print "Name\t\tNumber"} {printf "%-15s %s\n",$1,$3}' grade.txt
    9.2.11    向一行awk命令传值
    在awk执行前将值传入awk变量,需要将变量放在命令行下,格式:
    awk 命令变量=输入文件值
    举例:
    $ awk '{if ($5 < AGE) print $0}' AGE=10 grade.txt
    查询可用空间小于36000M的分 区:
    $ df -m|awk '($4 ~ /^[0-9]/) {if ($4 < LIMIT) print $6"\t"$4}' LIMIT=36000
    awk也允许传入环境变量。举例:
    查询当前用户登陆在哪个端口:
    $ who|awk '{if ($1 == user) print $1" you are connected to "$2}' user=$LOGNAME
    9.2.12    awk脚本文件
    可以将awk脚本写入一个文件再执行它。使用awk脚本的好处是不比每次使用时都需要重新输入,并且可以增加注释便于理解。拿一 个awk脚本举例:
    #!/bin/awk -f
    # all comment lines must start with a hash '#'
    # name: student_total.awk
    # to call: student_total.awk grade.txt
    # prints total and average of club student points

    # print a header first
    BEGIN{
    print "Student\t\tDate\tNumber\tGrade\tAge\tPoints\tMax"
    print "Name\t\tJoined\t\t\t\tGained\tPoint Available"
    print "========================================================================"
    }

    # let's add the scores of points gained
    (total += $6)

    # finished processing now let's print the total and average point
    END {
    print "Club Student Total points: " total
    print "Average Club Student points: " total/NR
    }
    第一行是#!/bin/awk -f,这一行很重要,没有它脚本将不能执行,因为它告知脚本系统中awk的位置。通过将命令分开,脚本的可读性提高,还可以在命令之间加入注释。
    执 行时在脚本文件后键入文件名,但需要先赋予可执行权限。
    9.2.13    在awk中使用FS变量
    使用awk脚本时,设置FS变量是在 BEGIN部分。如果不这样,awk不知道域分隔符是什么。
    脚本举例:(该脚本从/etc/passwd中抽取第一和第五域)
    #!/bin/awk -f
    # to call: passwd.awk /etc/passwd
    # print out the first and fifth fields
    BEGIN {
    FS=":"}
    {print $1,"\t",$5}

    9.2.14    向awk脚本传值
    向awk脚本传值与向awk命令行传值方式大体相同,格式:
    awk_script var=value input_file
    举例:
    #!/bin/awk -f
    # name: age.awk
    # to call: age.awk AGE=n grade.txt
    # prints ages that are lower than the age supplied on the command line
    {if ($5 < AGE)
    print $0}
    执行方式: (别忘了先赋予可执行权限)
    $ ./age.awk AGE=10 grade.txt
    也可以使用管道命令将命令的结果传递给awk脚 本,如
    $ cat grade.txt |./ student_total.awk
    9.2.15    awk数组
    数组使用前 不必定义,也不必指定数组元素个数。经常使用循环来访问数组,下面是一种循环类型的基本结构:
    for (element in array) print array[element]
    举例:(前面提到过的字符串123#456#789)
    #!/bin/awk -f
    # name: arraytest.awk
    # prints out an array
    BEGIN {
    record="123#456#789";
    split(record,array,"#")
    }
    END {
    for (i in array) {
    print array[i]
    }
    }
    使用/dev/null作为输入运 行脚本:
    $ ./arraytest.awk /dev/null

    从指定文本里找出匹配条件的项及其出现的次数
    #!/bin/awk -f
    # name: count.awk
    # to call: count.awk grade2.txt
    # loops through the grade2.txt file and counts how many belts we have in(yellow, orange, red)
    # also count how many adults and juniors we have
    # start of BEGIN
    # set FS and load the arrays with our values
    BEGIN {FS="#"
    # load the belt colours we are interested in only
    belt["Yellow"]
    belt["Orange"]
    belt["Red"]
    # end of BEGIN
    # load the student type
    student["Junior"]
    student["Senior"]
    }
    # loop thru array that holds the belt colours against field-1
    # if we have a match, keep a running total
    {for (colour in belt)
      {if ($1 == colour)
      belt[colour]++}}
    # loop thru array that holds the student type against
    # field-2 if we have a match, keep a running total
    {for (senior_or_junior in student)
      {if ($2 == senior_or_junior)
      student[senior_or_junior]++}}

    # finished processing so print out the matches..for each array
    END {for (colour in belt) print "The club has", belt[colour], colour, "Belts"

    for (senior_or_junior in student) print "The club has", student[senior_or_junior], senior_or_junior, "students"}
    BEGIN部分设置域分隔 符为#,初始化两个数组的内容元素。然后处理文件,先给数组命名为colour,使用循环语句比对$1是否等于数组元素之一(Yellow、Orange 或Red),如果匹配,依照匹配元素将运行总数保存进数组。同样的方法处理数组senior_or_junior。END部分打印浏览结果,对每一个数组 使用循环语句并打印 

  • 相关阅读:
    获取网页页面高度
    统计建模与R软件习题二答案
    R for installing package 'omg'
    R: for installing package 'RODBC'
    svm
    map(int, ..) 与 int() 的区别
    python: list[-1] 与 list[-1:] 的区别
    logisticregression
    bayes
    机器学习之python: kNN
  • 原文地址:https://www.cnblogs.com/wyxy2005/p/1753723.html
Copyright © 2020-2023  润新知