zoukankan      html  css  js  c++  java
  • awk命令拷屏

    如果不指明采取什么动作,awk默认打印出所有浏览出的记录,与{print $0}是一样的
    模式和动作两者是可选的,如果没有模式,则action应用到全部记录,如果没有action,则输出匹配全部记录。
    默认情况下,每一个输入行都是一条记录,但用户可通过RS变量指定不同的分隔符进行分隔。

    awk 指令由模式、操作或者模式与操作的组合组成。
    模式是由某种类型的表达式组成的语句。如果某个表达式中没有出现关键字 if ,但实际在计算时却暗含 if 这个词,那么这个表达式就是模式。
    操作由括在大括号中的一条或多条语句组成,语句之间用分号或者换行符隔开。
    分号常用在命令行上,换行符常用在脚本文件里。
    模式不能括在大括号中,模式由包括在两个正斜杠之间的正则表达式、一个或多个 awk 操作符组成的表达式组成。

    awk 是一种用于读取和处理结构化数据(如系统的 /etc/passwd 文件)的极佳工具。
    模式动作的语法
    awk 通过判断模式(Pattern)的值来决定是否执行其后对应的动作(Actions)。 pattern模式为主 ###匹配每行第5个字段以4,开头的行 [root@
    250-shiyan dev]# cd /dev [root@250-shiyan dev]# ll|awk '$5~/^4,/' ###匹配每行第3个字段为0的行 [root@250-shiyan sh]# ps -ajx|awk '$3~/^0$/' Warning: bad syntax, perhaps a bogus '-'? See /usr/share/doc/procps-3.2.8/FAQ 0 2 0 0 ? -1 S 0 0:00 [kthreadd] 2 3 0 0 ? -1 S 0 0:00 [migration/0] 2 4 0 0 ? -1 S 0 0:00 [ksoftirqd/0] 2 5 0 0 ? -1 S 0 0:00 [migration/0] [root@250-shiyan sh]# ps -ajx|awk '$3!~/^0$/' Warning: bad syntax, perhaps a bogus '-'? See /usr/share/doc/procps-3.2.8/FAQ PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND 0 1 1 1 ? -1 Ss 0 0:01 /sbin/init 1 381 381 381 ? -1 S<s 0 0:00 /sbin/udevd -d 1 958 958 958 ? -1 S<sl 0 0:04 auditd 1 997 997 997 ? -1 Ss 32 0:05 rpcbind [root@250-shiyan awk]# 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 Brown-2 12 30 28 ###模式可以是以下任意一个: /正则表达式/:使用通配符的扩展集。 关系表达式:可以用下面运算符表中的关系运算符进行操作,可以是字符串或数字的比较,如$2>%1选择第二个字段比第一个字段长的行。 模式匹配表达式:用运算符~(匹配)和~!(不匹配)。 模式,模式:指定一个行的范围。该语法不能包括BEGIN和END模式。 BEGIN:让用户指定在第一条输入记录被处理之前所发生的动作,通常可在这里设置全局变量。BEGIN是awk 的保留字,是一种特殊的模式。所以在BEGIN{ Actions} 语法中 END:让用户在最后一条输入记录被读取之后发生的动作。END是awk 的保留字,也是一个特殊的模式。
    在Unix awk中两个特别的表达式,BEGIN和END,这两者都可用于pattern中(参考前面的awk语法),提供BEGIN和END的作用是给程序赋予初始状态和在程序结束之后执行一些扫尾的工作。
    任何在BEGIN之后列出的操作(在{}内)将在Unix awk开始扫描输入之前执行,而END之后列出的操作将在扫描完全部的输入之后执行。因此,通常使用BEGIN来显示变量和预置(初始化)变量,使用END来输出最终结果。
    复合表达式最好用小括号括起来。
    fgy@fgy-QTH6:~$ awk -F: '(NR>=2&&NR<=10){print $1}' /etc/passwd
    daemon
    bin
    sys
    sync
    games
    man
    lp
    mail
    news


    以上介绍的模式计算后结果为一逻辑值(True or  False)。awk 各个逻辑值间可通过&&(and),||(or),!(not) 结合成一个新的逻辑值,
    所以可以将不同的逻辑值通过上述结合符号来结合成一个新的模式,这样可进行复杂的条件判断。
    ###
    /正则表达式/:使用通配符的扩展集。 [root@250-shiyan awk]# cat pa.awk /^(L|P)/ [root@250-shiyan awk]# awk -f pa.awk grade.txt P.Bunny 02/99 48 Yellow 12 35 28 L.Tansley 05/99 4712 Brown-2 12 30 28 [root@250-shiyan awk]# cat pa.awk /^(L|P)/ /[uo]l/ [root@250-shiyan awk]# awk -f pa.awk grade.txt 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 Brown-2 12 30 28 ###关系表达式和正则表达式混合的模式 [root@250-shiyan awk]# cat pa.awk $5 ~ /^[0-9]$/ [root@250-shiyan awk]# awk -f pa.awk grade.txt M.Tansley 05/99 48311 Green 8 40 44 J.Lulu 06/99 48317 green 9 24 26 ###关系表达式:可以用运算符表中的关系运算符进行操作,可以是字符串或数字的比较,如$2>$1选择第二个字段比第一个字段长的行。 [root@250-shiyan awk]# cat pa.awk $5 > 10 && $6 < 31 [root@250-shiyan awk]# awk -f pa.awk grade.txt J.Troll 07/99 4842 Brown-3 12 26 26 L.Tansley 05/99 4712 Brown-2 12 30 28 ###模式,模式:指定一个行的范围。该语法不能包括BEGIN和END模式。 [root@250-shiyan awk]# cat pa.awk $6 == 24 , $6 == 26 [root@250-shiyan awk]# awk -f pa.awk grade.txt 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 ###BEGIN:让用户指定在第一条输入记录被处理之前所发生的动作,通常可在这里设置全局变量。因为 awk 在开始处理输入文件之前会执行 BEGIN 块,因此它是初始化 FS(字段分隔符)变量、打印页眉或初始化其它在程序中以后会引用的全局变量的极佳位置。 BEGIN and END patterns cannot have missing action parts. ###END:让用户在最后一条输入记录被读取之后发生的动作。awk 还提供了另一个特殊块,叫作 END 块。awk 在处理了输入文件中的所有行之后执行这个块。通常,END 块用于执行最终计算或打印应该出现在输出流结尾的摘要信息。 ###空格的话,输出是相连的 [root@250-shiyan awk]# cat pa.awk /[uo]l/ {print $3 $5} [root@250-shiyan awk]# awk -f pa.awk grade.txt 483179 484212 action操作为主 操作由一个或多个命令、函数、表达式组成,之间由换行符或分号隔开,并位于大括号内。主要有四部份: 变量或数组赋值 输出命令 内置函数 控制流命令 ### [root@250-shiyan awk]# cat pa.awk $5 ~ /^[0-9]$/ {print $6 + 10} [root@250-shiyan awk]# awk -f pa.awk grade.txt 50 34 ### [root@250-shiyan awk]# cat pa.awk $4 == "Brown-3" {print $3} [root@250-shiyan awk]# awk -f pa.awk grade.txt 4842 ### [root@250-shiyan awk]# cat pa.awk {print ($6 > 30 ? "ok "$6: "error "$6)} [root@250-shiyan awk]# awk -f pa.awk grade.txt ok 40 error 24 ok 35 error 26 error 30 模式与操作组合为主 ###加逗号,输出是以空格分隔的 [root@250-shiyan awk]# cat pa.awk /[uo]l/ {print $3,$5} [root@250-shiyan awk]# awk -f pa.awk grade.txt 48317 9 4842 12 ###统计空白行 [root@250-shiyan awk]# cat blank BEGIN { x=0 } /^$/ { x=x+1 } END { print "I found " x " blank lines. :)" } [root@250-shiyan awk]# awk -f blank /etc/logrotate.conf I found 6 blank lines. :)
    ###统计某个文件夹下的文件占用的字节数,排除4096大小的文件
    [root@250-shiyan awk]# cat pa.awk
    BEGIN{size=0;print "[start] size is ", size}
    {if($5!=4096){size+=$5;print size}}
    END{print "[end]   size is ", size}
    [root@250-shiyan awk]# ll|awk -f pa.awk
    [start] size is  0
    0
    86
    1441
    1485
    1716
    1847
    [end]   size is  1847
    ### shell#snmpwalk
    -v 2c -c flt123 192.168.2.250 hrSWRunPerfMem|sed '/: 0 KB/d'|cut -d " " -f4|awk '{s+=$1}END{print s}' 1.txt内容如下 1 1 1 1 2 2 3 2 3 3 4 5 shell#cat 1.txt |awk '{(list1+=$1)(list2+=$2)(list3+=$3)(list4+=$4)}END{print list1,list2,list3,list4}' 6 6 8 8 shell#awk '{col1+=$1;col2+=$2;col3+=$3;col4+=$4}END{print col1,col2,col3,col4}' file 以下三行同一结果,其中一些细节有差异而已。统计某个文件夹下的文件占用的字节数,过滤4096大小的文件(一般都是文件夹): ls -l |awk 'BEGIN {size=0;print "[start]size is ", size} {if($5!=4096){size+=$5;}} END{print "[end] size is ", size}' ls -l |awk 'BEGIN {size=0;print "[start]size is ", size} {if($5!=4096){size+=$5;}} END{print "[end] size is ", size/1024/1024,"M"}' ls -l |awk 'BEGIN {size=0;print "[start]size is ", size} {if($5!=4096){size=size+$5;}} END{print "[end]size is ", size/1024/1024,"M"}' [root@250-shiyan log]# cat messages-20141012|awk '/(STOP)|(error)/'  匹配出现STOP或者error的行 [root@250-shiyan log]# more messages-20141019|awk '/13/' 打印出任何域包含13的记录 [root@250-shiyan log]# more messages-20141019|awk '$2~/13/' 打印出第二个域包含13的记录 [root@250-shiyan log]# more messages-20141019|awk '$2!~/13/' 打印出第二个域不包含13的记录 [root@250-shiyan log]# more messages-20141019|awk '$3=="10:16:04"' 精确匹配 [root@250-shiyan log]# more messages-20141019|awk '/[Gg]reen/' 匹配大小写 [root@250-shiyan log]# more messages-20141019|awk '$3~/^...4/' 打印第3域中第四个字符是4的记录,^行首,.任意字符 [root@250-shiyan log]# cat cron-20141019|awk '/(Anacron)|(Job)/'使用|时,语句需要括起来,或关系 [root@250-shiyan log]# echo $PWD | awk -F/ '{print$NF}' 打印目录名
    action可以有多个语句,每个语句间用分号隔开,注意每个语句都是一个/pattern/{action}。 
    ###一个动作里有两个语句。形如://{//{gsub(..)};//{print $0}
    [root@250-shiyan awk]# cat >pa.awk
    {gsub(/42/,50);print $0}
    [root@250-shiyan awk]# awk -f pa.awk 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   4850    Brown-3   12    26     26
    L.Tansley       05/99   4712    Brown-2   12    30     28
    
    ###标准的一套模式与动作语法。这是个标准的/pattern/{action}写法
    [root@250-shiyan awk]# cat >pa.awk
    gsub(/42/,50){print $0}
    [root@250-shiyan awk]# awk -f pa.awk grade.txt
    J.Troll         07/99   4850    Brown-3   12    26     26
    
    ###这是两套模式与动作,用分号隔开,第一个省略动作,第二个省略模式。形如:/gsub()/{print $0};//{print $0} 
    [root@250-shiyan awk]# cat >pa.awk
    gsub(/42/,50);
    {print $0}
    [root@250-shiyan awk]# awk -f pa.awk 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   4850    Brown-3   12    26     26
    J.Troll         07/99   4850    Brown-3   12    26     26
    L.Tansley       05/99   4712    Brown-2   12    30     28

     awk的赋值比较

    [root@84-monitor ~]# lsof -c rpcbind|awk '/mem/'|awk '(to+=$7);END{print "FD total: " to}'
    rpcbind 32580  rpc  mem    REG              253,0    65928  521865 /lib64/libnss_files-2.12.so
    rpcbind 32580  rpc  mem    REG              253,0  1921176  521231 /lib64/libc-2.12.so
    rpcbind 32580  rpc  mem    REG              253,0   142640  521255 /lib64/libpthread-2.12.so
    rpcbind 32580  rpc  mem    REG              253,0    19536  521861 /lib64/libdl-2.12.so
    rpcbind 32580  rpc  mem    REG              253,0    36584  521220 /lib64/libgssglue.so.1.0.0
    rpcbind 32580  rpc  mem    REG              253,0   113432  521863 /lib64/libnsl-2.12.so
    rpcbind 32580  rpc  mem    REG              253,0   162016  521225 /lib64/libtirpc.so.1.0.10
    rpcbind 32580  rpc  mem    REG              253,0    40792  521329 /lib64/libwrap.so.0.7.6
    rpcbind 32580  rpc  mem    REG              253,0   154624  521489 /lib64/ld-2.12.so
    FD total: 2656728
    
    ####列出FD是mem的列,将其大小列相加并输出 [root@
    84-monitor ~]# lsof -c rpcbind|grep mem|awk '{to+=$7};END{print "total: " to}' total: 2656728
    ####将123列相加,并输出
    [root@84-monitor ~]# size /usr/bin/ab|tail -1|awk '(a=$1+$2+$3);{print a}'
      45491    2072   15848   63411    f7b3 /usr/bin/ab
    63411
    action可以有多个语句,每个语句间用分号隔开,注意每个语句都是一个
    /pattern/{action}。 END是awk 的保留字,也是一个特殊的模式。 模式可以是其中之一 关系表达式 正则表达式等 复合表达式最好用小括号括起来。 这是两套模式与动作,用分号隔开,第一个省略动作,第二个是标准的模式与动作 awk '(to+=$7);END{print "FD total: " to}'

     awk的管道与重定向

    [root@250-shiyan ~]# lsof -c rpcbind|grep mem|awk '{print $7,$8 > "rpcmem"}'
    [root@250-shiyan ~]# cat rpcmem
    65928 260640
    1921216 260624
    142640 260648
    19536 260630
    36584 261105
    113432 260634
    162016 261107
    40792 260725
    154520 260617

    只能有一个管道,系统命令用双引号括起来。
    一般默认的sort都是按照字母的ASCII进行排序的,现在想按照数字的大小进行排序 对第一列按照大小排序sort
    -n [root@250-shiyan ~]# lsof -c rpcbind|grep mem|awk '{print $7|"sort"}' 113432 142640 154520 162016 1921216 19536 36584 40792 65928 [root@250-shiyan ~]# lsof -c rpcbind|grep mem|awk '{print $7|"sort -n"}' 19536 36584 40792 65928 113432 142640 154520 162016 1921216 默认sort是以空格或者tab键分隔字段,如果是其它的就加上-t ","之类的分隔符 对第二列按照大小排序sort -n -k2 [root@250-shiyan ~]# lsof -c rpcbind|grep mem|awk '{print $7,$8}' 65928 260640 1921216 260624 142640 260648 19536 260630 36584 261105 113432 260634 162016 261107 40792 260725 154520 260617 [root@250-shiyan ~]# lsof -c rpcbind|grep mem|awk '{print $7,$8|"sort -n -k2"}' 154520 260617 1921216 260624 19536 260630 113432 260634 65928 260640 142640 260648 40792 260725 36584 261105 162016 261107

    过滤出3月31日9点到12点的日志,grep需要两条命令
    grep -E "Mar 31 0[89]:" messages > efieji
    grep -E "Mar 31 1[012]:" messages > wefef
    下面这个命令是有问题的,它不能达到纯过滤3月31日9点到10点的日志。
    grep -E "Mar 31 09:|10:" messages
    下面这条可以一次达到目的,三条命令的进化过程,思考过程由简单到复杂,命令由复杂到简单。
    awk -F "]" '$1~/Mar 31 09:|Mar 31 1[012]:/{print $0}' messages >iii
    awk '/Mar 31 (09:|10:|11:|12:)/' messages  >oooo
    awk '/Mar 31 (09:|1[012]:)/' messages  >uuu 

  • 相关阅读:
    002Python和JS的不同进制之间的转换实现
    001JS中的非严格相等 ==
    028_同步本地git项目到github和码云
    015你所常见的日常英语
    001CSS三大特性
    014国家地区语言缩写码
    013常用的英语词典Share
    012_犯人的夏日的蚊虫叮咬词汇
    011_中文"上火"的英文怎么说
    我的IT之路这样走过
  • 原文地址:https://www.cnblogs.com/createyuan/p/4094205.html
Copyright © 2011-2022 走看看