• 三剑客之awk


    三剑客之awk

    第1章 awk简介

    1.1 awk简介

    • 一种名字怪异的语言。
    • 模式扫描和处理。处理文本流,水流。

    awk不仅仅是linux系统中的一个命令,而且是一种编程语言,可以用来处理数据和生成报告。

    处理的数据可以是一个或多个文件,可以是来自标准输入,也可以通过管道获取标准输入,awk可以

    在命令行上直接编辑命令进行操作,也可以编写成awk程序来进行更为复杂的运用。这里主要讲解

    awk命令行的运用。

    学完本章你会了解:

    • 域(字段)与记录
    • 模式与匹配
    • 基本的awk执行过程
    • awk常用内置变量(预定义变量)
    • awk数组(工作中比较常用)

    还有一些其他awk用法:(这里不作介绍)

    • awk语法:循环,条件
    • awk常用函数print
    • awk传递参数
    • awk引用shell变量
    • awk编程

    1.2 awk环境简介

    [root@linux-node1 ~]# cat /etc/redhat-release

    CentOS release 6.6 (Final)

    [root@linux-node1 ~]# uname -r

    2.6.32-504.el6.x86_64

    [root@linux-node1 ~]# awk --version

    GNU Awk 3.1.7

    [root@linux-node1 ~]# which awk

    /bin/awk

    #/bin下和/sbin下的命令区别:

    /bin : commands in this dir are all system installed user commands    系统的一些指令

    /sbin:  commands in this dir are all system installed super user commands  超级用户指令 系统管理命令,这里存放的是系统管理员使用的管理程序 

    /usr/bin: user commands for applications  后期安装的一些软件的运行脚本

    /usr/sbin: super user commands for applications  超级用户的一些管理程序

    1.3 awk的格式

    awk指令是由模式,动作,或者模式和动作的组合组成。

    模式既pattern,可以类似理解成sed的模式匹配,可以由表达式组成,也可以是两个正斜杠之间的正则表达式。比如NR=1,这就是模式,可以把他理解为一个条件。

    动作即action,是由在大括号里面的一条或多条语句组成,语句之间用分号隔开。如awk使用格式:

     

    图1-1 awk命令行格式

    awk处理的内容可以来自标准输入(<),一个或多个文本文件或管道。

    图1-2 awk模式动作解释图

    pattern既模式,也可以理解为条件,也叫找谁,你找谁?高矮,胖瘦,男女?都是条件,既模式。

    action 既动作,可以理解为干啥,找到人之后你要做什么。

    1.4 awk执行过程

    在深入了解awk前,我们需要知道awk如何处理文件的。

    示例1-1 示例文件的创建

    [root@linux-node1 ~]# mkdir -p /server/files/

    [root@linux-node1 ~]# head /etc/passwd > /server/files/awkfile.txt

    [root@linux-node1 ~]# cat /server/files/awkfile.txt  

    root:x:0:0:root:/root:/bin/bash

    bin:x:1:1:bin:/bin:/sbin/nologin

    daemon:x:2:2:daemon:/sbin:/sbin/nologin

    adm:x:3:4:adm:/var/adm:/sbin/nologin

    lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

    sync:x:5:0:sync:/sbin:/bin/sync

    shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown

    halt:x:7:0:halt:/sbin:/sbin/halt

    mail:x:8:12:mail:/var/spool/mail:/sbin/nologin

    uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin

    [root@linux-node1 ~]# awk 'NR>=2{print $0}' /server/files/awkfile.txt

    bin:x:1:1:bin:/bin:/sbin/nologin

    daemon:x:2:2:daemon:/sbin:/sbin/nologin

    adm:x:3:4:adm:/var/adm:/sbin/nologin

    lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

    sync:x:5:0:sync:/sbin:/bin/sync

    shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown

    halt:x:7:0:halt:/sbin:/sbin/halt

    mail:x:8:12:mail:/var/spool/mail:/sbin/nologin

    uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin

    [root@linux-node1 ~]# awk 'NR>=2{print NR,$0}' /server/files/awkfile.txt

    2 bin:x:1:1:bin:/bin:/sbin/nologin

    3 daemon:x:2:2:daemon:/sbin:/sbin/nologin

    4 adm:x:3:4:adm:/var/adm:/sbin/nologin

    5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

    6 sync:x:5:0:sync:/sbin:/bin/sync

    7 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown

    8 halt:x:7:0:halt:/sbin:/sbin/halt

    9 mail:x:8:12:mail:/var/spool/mail:/sbin/nologin

    10 uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin

    awk是通过一行一行的处理文件,这条命令中包含模式部分(条件)和动作部分(动作),awk将处理模式指定的行。

    小结awk执行过程:

    aawk读入第一行内容

    b)判断符合模式中的条件(NR>=2

    如果匹配默认则执行对应的动作({print $0})

    l 如果不匹配条件,继续读取下一行

    c))继续读取下一行

    d)重复过程a-c,直到读取到最后一行(EOF:end of file)

     1.5 区域和记录

    名称

    含义

    field

    域,区域,字段

    record

    记录,默认一整行

    eg$1,$2,$3,$NF

    $0: 整行,一个记录

    $ 取 引用

    1.5.1 字段(区域)

    每条记录都是由多个字段(field)组成的,默认情况下之间的分隔符是由空白符(即空格或制表符)来分隔,并且将分隔符记录在内置变量FS中。每行记录的字段数保存在awk的内置变量NF中。

    1-4 awk区域分隔符

    awk使用内置变量FS来记录字段分隔符的内容,可以通过BEGIN语句来更改,也可以在命令行上通过-F参数来更改,下面通过示例来加强学习。

    示例1-3  FS演示文件生成

    [root@linux-node1 ~]# awk -F ":" 'NR>=2&&NR<=5{print $1,$3}' /server/files/awkfile.txt

    bin 1

    daemon 2

    adm 3

    lp 4

    1.5.2记录

    awk对每个要处理的输入数据人为都是具有格式和结构的,而不仅仅是一堆字符串。默认情况下,每一行内容都成为一条记录,并以换行符结束。

    ² 默认情况 -一行==一个记录,每行都是一个记录。

    ² RS ==record separator 每个记录读入的时候的分隔符。

    ² NR==number of record 行号,记录的数。awk当前处理着的,记录的数。

    ² ORS==output record separate 输出食肉的分隔符

    awk使用内置变量来存放记录分隔符,RS表示的是输入的记录分隔符,这个值也可以以特定的方式修改。

    前面我们讲到过的$0awk使用$0来表示整条记录。记录分隔符 保存在RS变量中。另外awk对每一行的记录号都有一个内置变量NR来保存,每处理完一条记录NR的值就会自动+1.

    下面通过示例来加强一下什么是记录,记录分隔符。

    示例1-5 NR记录行号

    [root@linux-node1 files]# awk '{print NR,$0}' awkfile.txt

    1 root:x:0:0:root:/root:/bin/bash

    2 bin:x:1:1:bin:/bin:/sbin/nologin

    3 daemon:x:2:2:daemon:/sbin:/sbin/nologin

    4 adm:x:3:4:adm:/var/adm:/sbin/nologin

    5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

    6 sync:x:5:0:sync:/sbin:/bin/sync

    7 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown

    8 halt:x:7:0:halt:/sbin:/sbin/halt

    9 mail:x:8:12:mail:/var/spool/mail:/sbin/nologin

    10 uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin

    示例1-6 RS记录分隔符

    #/为分隔符记录一行

    [root@linux-node1 files]# awk 'BEGIN{RS="/"}{print NR,$0}' awkfile.txt

    1 root:x:0:0:root:

    2 root:

    3 bin

    4 bash

    bin:x:1:1:bin:

    5 bin:

    6 sbin

    7 nologin

    daemon:x:2:2:daemon:

    8 sbin:

    9 sbin

    10 nologin

    adm:x:3:4:adm:

    11 var

    12 adm:

    13 sbin

    14 nologin

    lp:x:4:7:lp:

    15 var

    16 spool

    17 lpd:

    18 sbin

    19 nologin

    #以:为分隔符记录一行

    [root@linux-node1 files]# awk 'BEGIN{RS=":"}{print NR,$0}' awkfile.txt  

    1 root

    2 x

    3 0

    4 0

    5 root

    6 /root

    7 /bin/bash

    bin

    8 x

    9 1

    10 1

    11 bin

    12 /bin

    13 /sbin/nologin

    daemon

    14 x

    15 2

    16 2

    17 daemon

    18 /sbin

    19 /sbin/nologin

    adm

    20 x

    21 3

    22 4

    23 adm

    24 /var/adm

    25 /sbin/nologin

    lp

    26 x

    27 4

    28 7

    29 lp

    30 /var/spool/lpd

    31 /sbin/nologin

    awk 眼中的文件,从头到尾一段连续的字符串,恰巧中间有些 (回车换行符)

    示例1-7 RS为空值

    #RS为空值的时候将指定行输出为一行

    [root@linux-node1 files]# awk 'BEGIN{RS=""}{print NR,$1,$2,$3}' awkfile.txt  

    说明:

    在行首打印输出记录号,并打印出每一行$0的内容

    企业案例1:计算文件中每个单词的重复数量

    [root@linux-node1 files]# sed -ri.bak 's#[:/0-9]+# #g' awkfile.txt

    1)单词弄成一列(排队)

    其中 -o 表示“only-matching 精确匹配

    [root@linux-node1 files]# egrep -o "[a-zA-z]+" awkfile.txt |sort| uniq -c|sort -r

          5 x

          5 sbin

          4 nologin

          4 bin

          3 root

          3 adm

          2 var

          2 lp

          2 daemon

          1 spool

          1 lpd

          1 bash

    2)统计

    [root@linux-node1 files]# awk 'BEGIN{RS="() | "}{print $0}' awkfile.txt|sort |uniq -c|sort -rn

          5 x

          5 sbin

          4 nologin

          4 bin

          3 root

          3 adm

          2 var

          2 lp

          2 daemon

          1 spool

          1 lpd

          1 bash

          1

    企业案例2: 统计文件中每个字母的重复数量

    记录小结:

    1. 大象放冰箱分几步?打开冰箱,把大象放进去,关闭冰箱门。
    2. 多用NRNF$数字,配合你进行调试awk命令。
    3. NR存放着每个记录的号(行号)读取新行时候会自动+1
    4. RS是记录的分隔符,简单理解就是可以指定每个记录的结尾标志。
    5. (用RS替换
    6. RS作用就是表示一个记录的结束。
    7. FS标识着每个区域的结束。

    1.6 模式匹配

    1.6.1 正则表达式

    awk支持的正则表达式元字符

    元字符

    功能

    示例

    解释

    ^

    字符串开头

    /^cool/

    匹配所有以cool开头的字符串

    $

    字符串结尾

    /cool$/

    匹配所有以cool结尾的字符串

    .

    匹配任意单个字符

    (包括回车符)

    /c..l/

    匹配字母c,然后两个任意字符,再以l结尾的行,比如ckk1c@#1

    *

    匹配0个或多个前导字符

    /a*cool/

    匹配0个或多个a之后紧跟着cool的行,比如coolaaacool

    +

    重复一次或一次以上

    /a+b/

    匹配一个或多个ab的行

    匹配0个或一个前导字符

    /a?b/

    匹配bab的行

    []

    匹配指定字符组内的任一个字符

    /^[abc]/

    匹配以字母abc开头的行

    [^]

    匹配不在指定字符组

    /^[^abc]/

     匹配不以字母abc开头的行

    x{m}

    x重复m

    x重复至少m

    x重复至少m次,但不超过n

    需要指定参数:--posix或者--re-interval

    /(cool){5}

    需要注意的一点是,cool加括号或不加括号的区别,x可以使字符串也可以只是一个字符,所有/cool{5}/表示匹配coo再加上5l,即coolllll

    ^(cool){2,}则表示匹配coolcool

    coolcoolcool

    x{m,}

    /(cool){2,}/

    /(cool){5,6}/

    正则表达式的运用,默认是在行内查找匹配的字符串,若有匹配则执行action操作,但是有时候仅需要固定的列来匹配指定的正则表达式,比如:$3这一列查找匹配tom的行,这样就需要另外两个匹配操作符:

    ~:用于对记录或字段的表达式进行(匹配)

    !~:用于表达与~想法的意思。(不匹配)

    #匹配 第五列以l或者a开头的所有行 ,这里(l|a) 可以换成[al]

    [root@linux-node1 files]# awk '$3~/^(l|a)/{print $0}' awkfile.txt

    adm x adm var adm sbin nologin

    lp x lp var spool lpd sbin nologin

    #eth0 ip

    [root@linux-node1 files]# ifconfig eth0| awk -F "[ :]+" 'NR==2{print $4}'

    10.0.0.7

    [root@linux-node1 files]# ifconfig eth0| awk -F "addr:| Bcast:" 'NR==2{print $2}'  

    10.0.0.7

    [root@linux-node1 files]# echo "-----=====1#######2"

    -----=====1#######2

    [root@linux-node1 files]# echo "-----=====1#######2"|grep "[-=#]"

    -----=====1#######2

    [root@linux-node1 files]# echo "-----=====1#######2"|grep -o "[-=#]"

    -

    -

    -

    -

    -

    =

    =

    =

    =

    =

    #

    #

    #

    #

    #

    #

    #

    [root@linux-node1 files]# echo "-----=====1#######2"|egrep -o "[-=#]+"

    -----=====

    #######

    #匹配o出现一次或者两次的行打印第一列和最后一列

    [root@linux-node1 files]# awk --posix '$1~/o{1,2}/{print NR,$1,$NF}' awkfile.txt

    1 root bash

    3 daemon nologin

    1.6.2比较表达式

    示例1-18

    [root@linux-node1 files]# awk 'NR>=2&&NR<=5{print NR,$0}' awkfile.txt

    2 bin x bin bin sbin nologin

    3 daemon x daemon sbin sbin nologin

    4 adm x adm var adm sbin nologin

    5 lp x lp var spool lpd sbin nologin

    1.6.3范围模式

    awk ‘/start pos/,/end pos/{print $0} ‘ test.txt

    awk ‘/start pos/,NR==XXX{print $0}’ passwd.oldboy

    范围模式的时候,范围条件的时候,表达式必须匹配一行,

    [root@linux-node1 files]# awk 'NR==2,NR==5{print NR,$1,$3}' awkfile.txt

    2 bin bin

    3 daemon daemon

    4 adm adm

    5 lp lp

    [root@linux-node1 files]# awk 'NR==2,NR==5{print NR,$0}' awkfile.txt      

    2 bin x bin bin sbin nologin

    3 daemon x daemon sbin sbin nologin

    4 adm x adm var adm sbin nologin

    5 lp x lp var spool lpd sbin nologin

    [root@linux-node1 files]# awk 'NR==2,NR<=5{print NR,$0}' awkfile.txt  

    2 bin x bin bin sbin nologin

    1.6.4企业案例:取出常用服务端口号

    ftp http https mysql ssh 端口号 /etc/services 文件

    [root@linux-node1 files]# awk -F "[ /]+" '$1~/ftp|https|mysql|ssh)$/{print $1,$2}' /etc/services|uniq

    小结:

    1. 模式===》条件
    2. 正则表达式
    3. 条件表达式(NR>=2 NR==2
    4. 范围表达式
    5. NR==2,NR==5
    6. /正则表达式-开始//正则结束/
    7. $1~/正则表达式-开始/,$3~/正则结束/ 行,记录。
    8. 区域:FS刀分隔的,FS区域分隔符
    9. 记录:RS刀分隔的,RS记录分隔符
    10. FS===>NF 区域的数量
    11. RS===>NR 记录号,随着记录的增加NR自动+1

     

    1.7 awk结构的回顾

    1.7.1 BEGIN模块

    BEGIN模式之前我们有在示例中提到,自定义变量,给内容变量赋值等,都是用过。需要注意的是BEGIN模式后面要接跟一个action操作块,包含在大括号内。awk必须在对输入文件进行任何处理前先执行BEGIN定义的action操作块。我们可以不要任何输入文件,就可以对BEGIN模块进行测试,因为awk需要先执行完BEGIN模式,菜对输入文件做处理。BEGIN模式常常被用来修改内置变量ORS,RS,FS,OFS等的值。

    示例1-25

    [root@linux-node1 files]# awk 'BEGIN{print "this is begin! and thiscommand donnot have file"}'

    this is begin!

    and thiscommand donnot have file

    说明:

    没有文件awk依旧可以处理BEGIN模式下的操作块。

    1.7.2 END模块

    END awk读取完所有的文件的时候

    awk编程思想:

    1.先处理,最后再END模块输出。

    BEGIN模式相对于的END模式,格式一样,但是END模式仅在awk处理完所有输入行后才进行处理。并且在END模式下awk不匹配任何输入行。

    1.7.3 总结awk执行过程

    1.读入一行

    2.判断是否是需要的行 条件$3>15 满足大于15 执行action print

    3.不满足条件重复1,2步骤

    1.7.4 企业案例3:统计文件里面的空行数量

    [root@linux-node1 files]# grep -c "^$" /etc/services

    16

    [root@linux-node1 files]# awk '/^$/{a=a+1;print a}' /etc/services  

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    [root@linux-node1 files]# awk '/^$/{a=a+1}END{print a}' /etc/services             

    16

     head -20 /etc/passwd >awkfile2.txt

    面试题:awkfile2.txt 里面 以:为分隔符,区域3大于15行,一共有多少个?

    [root@linux-node1 files]# awk -F ":" '$3>15{print $0}' awkfile2.txt   

    nobody:x:99:99:Nobody:/:/sbin/nologin

    dbus:x:81:81:System message bus:/:/sbin/nologin

    usbmuxd:x:113:113:usbmuxd user:/:/sbin/nologin

    vcsa:x:69:69:virtual console memory owner:/dev:/sbin/nologin

    rpc:x:32:32:Rpcbind Daemon:/var/cache/rpcbind:/sbin/nologin

    rtkit:x:499:497:RealtimeKit:/proc:/sbin/nologin

    #计算一次,输出一次

    [root@linux-node1 files]# awk -F ":" '$3>15{a=a+1;print a}' awkfile2.txt           

    1

    2

    3

    4

    5

    6

    #处理完文件以后再输出a   这里a=a+1 可以用a++代替

    [root@linux-node1 files]# awk -F ":" '$3>15{a=a+1;}END{print a}' awkfile2.txt        

    6

    企业面试题5:1+.....+100 1加到100的值,用awk实现

    root@linux-node1 files]# seq 100 > test.txt  

    [root@linux-node1 files]# cat test.txt |awk '{a+=$0}END{print a}'

    5050

    [[root@linux-node1 files]# awk 'a=a+$0;END{print a}' test.txt |sed -n '$p'

    5050

    1.7.4 企业案例4

    找出环境变量$PATH中,所有只有三个任意字符的命令,例如tee,并将他们重定向到command.txt中,要求一行显示1个,并在文件尾部统计他们的个数.

    [root@linux-node1 files]# find $(echo $PATH|tr ":" " ") -type f -name "???"| awk '{a++}END{print "result:"a}'

    find: `/root/bin': No such file or directory

    result:75

    通配符:用来匹配文件名的。{}字符序列

    正则表达:字符串

    1.7.5 总结awk执行过程

    [root@linux-node1 files]# awk -F ":" 'BEGIN{print FS}'        

    :

    先执行命令再执行BEGIN模块

    思想:

    1. awk核心思想就是现处理,然后END模块输出。(累加(a++a+=$0),awk数组)
    2. BEGIN模块用于awk内置变量FSRS的赋值,打印标题头的信息,(excel表格里面标题行)
    3. END模块用来最后输出,统计信息,awk数组信息。
    4. 区域,记录
    1. BEGINEND模块只能有一个。不能BEGIN{}BEGIN{}或者END{}END{}
    2. 找谁干啥模块,可以是多个。

    NR=2{print $1}NR=5{print $0}

    1.8awk内置变量(预定义变量)

    变量名

    属性

    $0

    当前记录

    $1-$n

    当前记录的第n个字段,字段间由FS分隔

    FS

    输入字段分隔符 默认是空格

    NF

    当前记录中的字段个数。就是有多少列

    NR

    已经读出的记录数,就是行号,从1开始

    RS

    输入的记录分隔符默认为换行符

    OFS

    输出字段分隔符 默认也是空格

    ORS

    输出的记录分隔符,默认为

    FNR

    当前文件的读入记录号

    1.9 awk数组

    示例1-9数组演示

    array[b]=”aaa”:array.....

    1.9.1企业面试题1

     

    处理以下文件内容,将域名取出并根据域名进行计数排序处理(去重):(百度和sohu面试题)

    [root@linux-node1 files]# cat awkfile3.txt

    http://www.etiantian.org/index.html

    http://www.etiantian.org/1.html

    http://post.etiantian.org/index.html

    http://mp3.etiantian.org/index.html

    http://www.etiantian.org/3.html

    http://post.etiantian.org/2.html

    [root@linux-node1 files]# awk -F "/" '{array[$3]++}END{for(key in array) print key,array[key]}' awkfile3.txt

    mp3.etiantian.org 1

    post.etiantian.org 2

    www.etiantian.org 3

    [root@linux-node1 files]# awk -F "/+" '{array[$2]++}END{for(key in array)print key,array[key]}'  awkfile3.txt

    mp3.etiantian.org 1

    post.etiantian.org 2

    www.etiantian.org 3

    小结:

    1. awk数组去重
    2. 选好分隔符 -F “/”
    3. 选好处理的区域,print $1,$3,$2
    4. array[$3]++
    5. 先处理,最后END模块输出
    6. 输出awk数组我们使用for(key in array)
    7. ===>for ()循环
    8. key in array 手去框里,抓苹果。
    9. key 就是苹果名字(数组元素的名字)
    10. array数组名(框的名字)
    11. 打印输出print key,array[key]

    1.9.2 企业案例2统计每个IP的访问量

    access_awk.log

    1.10 awk相关英语总结

    名称

    含义

    filed

    域,区域,字段

    record

    记录,默认一整行

    Filed Separator

    FS:区域分隔符,表示一个区域的结束,字段,域

    Number of Filed

    NF:每一个记录中区域的数量

    Record Separator

    RS:记录分隔符,表示每个记录的结束

    output filed separator

    OFS

    output Record Separator

    ORS

    awk当前处理的文件的记录号

    FNR

    [root@linux-node1 files]# seq 20 30 >20-30.txt

    [root@linux-node1 files]# seq 50 60 >50-60.txt

    [root@linux-node1 files]# awk '{print FNR,NR,$0}' 20-30.txt 50-60.txt

    1 1 20

    2 2 21

    3 3 22

    4 4 23

    5 5 24

    6 6 25

    7 7 26

    8 8 27

    9 9 28

    10 10 29

    11 11 30

    1 12 50

    2 13 51

    3 14 52

    4 15 53

    5 16 54

    6 17 55

    7 18 56

    8 19 57

    9 20 58

    10 21 59

    11 22 60

    2awk总结:

    2.1.找谁干啥模块

     

    2.2awk执行过程-完全

     

    BEGIN模块输出一些提示性文字。awk内置变量FS,RS,ORS,OFS

    END 模块输出一些提示性文字,显示最后的结果,计算空行,awk数组,去苹果的过程把苹果展示处理。

    awk里面的普通变量不用初始化。

    awk先处理,一行一行的处理,然后END模块输出。

    1. 域与记录

    FS指定各种各样的刀(正则表示),RS正则表达

    1. 模式匹配===》条件 如何找人。

    正则表达式

    ^字符串开头

    $字符串结尾

    $3~/^http$/

    --posix--re-interval

    r{n,m}

    匹配精确,模糊

    NR==1

    NR>=2

    模式默认匹配 一行$0

    $3~/^r/

    awk ‘$3~/[4-6]/{print $0}’ passwd.txt

    范围匹配

    NR=2,NR=5   ==>2,5p

    /start 位置/,/结束位置/

    1. 遇到正则表达式/ /
    2. $3~/reg/
    3. > = <
    4. NR==2,NR=5 /start位置//结束位置/
    1. awk数组

    数组 ==>元素

    一个筐==》苹果

    题目来源:

    http://edu.51cto.com/course/course_id-4319.html

    3. 考试题

    考试题1:处理以下文件内容,将域名取出并根据域名进行计数排序处理:(百度和sohu面试题)

    oldboy.log

    http://www.etiantian.org/index.html

    http://www.etiantian.org/1.html

    http://post.etiantian.org/index.html

    http://mp3.etiantian.org/index.html

    http://www.etiantian.org/3.html

    http://post.etiantian.org/2.html

    答案 4种)

    #这里的

    root@linux-node1 files]# awk -F "/" '{array[$3]++}END{for(key in array) print key,array[key]}' awkfile3.txt

    [root@linux-node1 files]# awk -F "/+" '{array[$2]++}END{for(key in array)print key,array[key]}'  awkfile3.txt

    [root@linux-node1 files]#  cut -d / -f3 awkfile3.txt|sort|uniq -c|sort -nrk2

    [root@linux-node1 files]#  sort -t / -rk3 awkfile3.txt|awk -F / '{print $3}'|uniq -c

     

    考试题2:统计企业工作中高并发web服务器不同网络连接状态对应的数量

    [root@linux-node1 files]# netstat -ant|awk 'NR>=3{array[$6]++}END{for(key in array)print key,array[key]}'              

    TIME_WAIT 134

    SYN_SENT 1

    ESTABLISHED 5

    LISTEN 10

    [root@linux-node1 files]# netstat -ant|awk '{print $6}'|uniq -c|sort -nr

        138 TIME_WAIT

          7 LISTEN

          5 ESTABLISHED

          3 LISTEN

          1 Foreign

          1 established)

    考试题3.分析图片服务日志,把日志(每个图片访问次数*图片大小的总和)排行,取top10,也就是计算每个url的总访问大小【附加题:加分题】。

    说明:本题生产环境应用:这个功能可以用于IDC网站流量带宽很高,然后通过分析服务器日志哪些元素占用流量过大,进而进行优化或裁剪该图片,压缩js等措施。

    本题需要输出三个指标: 【访问次数】    【访问次数*单个文件大小】   【文件名(可以带URL)】

    测试数据

    59.33.26.105 - - [08/Dec/2010:15:43:56 +0800] "GET /static/images/photos/2.jpg HTTP/1.1" 200 11299 "http://oldboy.blog.51cto.com/static/web/column/17/index.shtml?courseId=43" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)"

    59.33.26.105 - - [08/Dec/2010:15:43:56 +0800] "GET /static/images/photos/2.jpg HTTP/1.1" 200 11299 "http://oldboy.blog.51cto.com/static/web/column/17/index.shtml?courseId=43" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)"

    59.33.26.105 - - [08/Dec/2010:15:44:02 +0800] "GET /static/flex/vedioLoading.swf HTTP/1.1" 200 3583 "http://oldboy.blog.51cto.com/static/flex/AdobeVideoPlayer.swf?width=590&height=328&url=/[[DYNAMIC]]/2" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)"

    124.115.4.18 - - [08/Dec/2010:15:44:15 +0800] "GET /?= HTTP/1.1" 200 46232 "-" "-"

    124.115.4.18 - - [08/Dec/2010:15:44:25 +0800] "GET /static/js/web_js.js HTTP/1.1" 200 4460 "-" "-"

    124.115.4.18 - - [08/Dec/2010:15:44:25 +0800] "GET /static/js/jquery.lazyload.js HTTP/1.1" 200 1627 "-" "-"

     

    答案:

    [root@linux-node1 files]# awk 'BEGIN{print"URL:"" ""num: ""total_size:"}{a[$7]++;b[$7]=$10}END{for(key in a)print key" "a[key]" "a[key]*b[key]}' images.log  

    URL:    num:    total_size:

    /?=     1       46232

    /static/js/web_js.js    1       4460

    /static/images/photos/2.jpg     2       22598

    /static/flex/vedioLoading.swf   1       3583

    /static/js/jquery.lazyload.js   1       1627

    理解透上述问题并搞定后,你将可以轻松搞定如下扩展的考试题:

    扩展考试题1:

    4.假如现在有个文本,格式如下:

    a  1

    b  3

    c  2

    d  7

    b  5

    a  3 

    g  2

    f  6

    d  9

    即左边是随机字母,右边是随机数字,要求写个脚本使其输出格式为:

    a  4

    b  8

    c  2

    d  16

    f  6

    g  2

    即将相同的字母后面的数字加在一起,按字母的顺序输出。

    答案:

    答案

    [root@linux-node1 files]# awk '{if(! a[$1]++)b[++n]=$1;c[$1]+=$2}END{for(i=1;i<=n;i++)print b[i],c[b[i]]}' a.txt

    a 4

    b 8

    c 2

    d 16

    g 2

    f 6

    扩展考试题2:用shell处理以下内容

    1、按单词出现频率降序排序!

    2、按字母出现频率降序排序!

    the squid project provides a number of resources to assist users design,implement and support squid installations. Please browse the documentation and support sections for more infomation

    1.答案

    [root@linux-node1 files]# sed -r 's#,| # #g' b.txt|awk '{array[$0]++}END{for(key in array) print array[key],key}'|sort -r          

    2 the

    2 support

    2 squid

    2 and

    1 users

    1 to

    1 sections

    1 resources

    1 provides

    1 project

    1 of

    1 number

    1 more

    1 installations.

    1 infomation

    1 implement

    1 for

    1 documentation

    1 design

    1 browse

    1 assist

    1 a

    1 Please

    1

    2.答案

    [root@linux-node1 files]# sed 's#[a-zA-Z]#& #g' b.txt|awk 'BEGIN{RS=" "}{arr[$1]++}END{for(i in arr) print arr[i],i}'|sort -nr     

    25

    19 s

    17 e

    16 o

    14 t

    12 n

    11 r

    11 i

    9 a

    8 u

    7 p

    7 d

    6 m

    4 l

    4 c

    3 f

    2 q

    2 h

    2 b

    1 w

    1 v

    1 j

    1 g

    1 P

    1 .

    1 ,i

  • 相关阅读:
    Chapter 4 持久存储数据对象
    pyhton Chapter3 读文件
    python笔记1
    C#读写txt文件
    机器学习第一讲
    Json对象
    表单加载
    多列树
    Java 基础【11】@注解
    Java 基础【06】复合赋值运算
  • 原文地址:https://www.cnblogs.com/benjamin77/p/7866076.html
Copyright © 2020-2023  润新知