一、使用awk提取文本

目标:

本案例要求使用awk工具完成下列过滤任务:

1> 练习awk工具的基本用法
    2> 提取本机的IP地址、根分区使用率
    3> 格式化输出/etc/passwd文件中的用户名、UID、宿主目录信息

格式化输出passwd文件内容时,要求第一行为列表标题,最后一行提示一共已处理文本的总行数,如下图所示。

步骤:

步骤一:awk文本过滤的基本用法

1)基本操作方法

格式:awk [选项] '[条件]{编辑指令}' 文件

其中,print 是最常用的编辑指令;若有多条编辑指令,可用分号分隔。

处理文本时,若未指定分隔符,则默认将空格、制表符等作为分隔符。

直接过滤文件内容:

[root@svr5 ~]# awk '{print $1,$2}' /etc/rc.local      //输出文件的第1、2列
    #!/bin/sh
    #
    # This
    # You
    # want
    touch /var/lock/subsys/local

结合管道过滤命令输出:

[root@svr5 ~]# uname -a                              //正常的完整输出
    Linux svr5.tarena.com 2.6.18-348.el5 #1 SMP Wed Nov 28 21:22:00 EST 2012 x86_64 x86_64 x86_64 GNU/Linux
    [root@svr5 ~]# uname -a | awk '{print $1,$3,$12}'      //输出第1、3、12字段
    Linux 2.6.18-348.el5 x86_64

2)选项 -F 可指定分隔符

截取/etc/passwd文件的前7行,用来创建一个测试文件,操作如下:

[root@svr5 ~]# head -7 /etc/passwd > passwd.txt
    [root@svr5 ~]# cat passwd.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

输出passwd.txt文件中以分号分隔的第1、7个字段,显示的不同字段之间以逗号隔开,操作如下:

[root@svr5 ~]# awk -F: '{print $1","$7}' passwd.txt
    root,/bin/bash
    bin,/sbin/nologin
    daemon,/sbin/nologin
    adm,/sbin/nologin
    lp,/sbin/nologin
    sync,/bin/sync
    shutdown,/sbin/shutdown

或者:

[root@svr5 ~]# awk -F ":" '{print $1","$7}' passwd.txt
    root,/bin/bash
    bin,/sbin/nologin
    daemon,/sbin/nologin
    adm,/sbin/nologin
    lp,/sbin/nologin
    sync,/bin/sync
    shutdown,/sbin/shutdown

awk还识别多种单个的字符,比如以“:”或“/”分隔,输出第1、10个字段:

[root@svr5 ~]# awk -F [:/] '{print $1,$10}' passwd.txt
    root bash
    bin nologin
    daemon nologin
    adm sbin
    lp
    sync sync
    shutdown shutdown

输出每次处理的行号,以及当前行以“:”分隔的字段个数:

[root@svr5 ~]# awk -F: '{print NR,NF}' passwd.txt
    1 7
    2 7
    3 7
    4 7
    5 7
    6 7
    7 7

3)awk处理的时机

awk会逐行处理文本,支持在处理第一行之前做一些准备工作,以及在处理完最后一行之后做一些总结性质的工作。在命令格式上分别体现如下:

行前处理,BEGIN{ }
    逐行处理,{ }
    行后处理,END{ }

上述编辑指令段可以包含在一对单引号内,比如:

awk  [选项]  ' BEGIN{编辑指令 } {编辑指令} END{编辑指令}'  文件

只做预处理的时候,可以没有操作文件,比如:

[root@svr5 ~]# awk 'BEGIN{A=1024;print A*2.56}'
    2621.44

举个包括三个处理时机的例子——“统计系统中使用bash作为登录Shell的用户总个数:预处理时赋值变量x=0,然后逐行读入/etc/passwd 文件检查,如果发现登录Shell是/bin/bash则x增加1,全部处理完毕后,输出x的值即可。相关操作及结果如下:

[root@svr5 ~]# awk 'BEGIN{x=0}/\<bash$/{x++} END{print x}' /etc/passwd
    29

当然,这个例子比较简单(效果与egrep -c '\<bash$' /etc/passwd 相同),此处仅仅是用来说明awk三种处理时机的用法。在实际工作中,利用awk的这种处理流程可以完成许多更复杂的任务。

步骤二:利用awk提取本机的IP地址、根分区使用率

1)提取IP地址

分步实现的思路及操作参考如下——

通过ifconfig eth0查看网卡信息,其中包括IP地址:

[root@svr5 ~]# ifconfig eth0
    eth0      Link encap:Ethernet  HWaddr 00:0C:29:82:09:E9
              inet 192.168.4.4  Bcast:192.168.4.255  Mask:255.255.255.0
              inet6 addr: fe80::20c:29ff:fe82:9e9/64 Scope:Link
              UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
              RX packets:358524 errors:0 dropped:0 overruns:0 frame:0
              TX packets:230638 errors:0 dropped:0 overruns:0 carrier:0
              collisions:0 txqueuelen:1000
              RX bytes:44470760 (42.4 MiB)  TX bytes:64236279 (61.2 MiB)

结合grep获得包含IP地址的那一行:

[root@svr5 ~]# ifconfig eth0 | grep "inet"
              inet addr:192.168.4.4  Bcast:192.168.4.255  Mask:255.255.255.0

再结合awk过滤出第2列:

[root@svr5 ~]# ifconfig eth0 | grep "inet" | awk '{print $2}'
    192.168.4.4

2)提取根分区使用率

分步实现的思路及操作参考如下——

通过df命令查看根分区的使用情况,其中包括使用率:

[root@svr5 ~]# df -hT /
    文件系统         类型     容量     已用     可用     已用%     挂载点
    /dev/sda2     ext3     19G         7.2G     11G         40%         /

输出上述结果中最后一行的第6列:

[root@svr5 ~]# df -hT / | tail -1 | awk '{print $6}'
    40%

步骤三:格式化输出/etc/passwd文件

1)任务需求及实现思路分析

根据任务要求的结果,输出的内容包括三个部分:列表头、用户信息、列表尾。

由于/etc/passwd文件中的用户记录是单一的以“:”分隔,而且恰好awk本身就已经支持“前、中、后”三段式处理,所以用awk处理是再合适不过了。通过awk的内置变量NR即可获得处理的记录行数,因此只要设置正确的输出即可。

2)根据实现思路编写、验证awk过滤语句

输出信息时,可以使用“\t”显示Tab制表位:

[root@svr5 ~]# awk -F: 'BEGIN{print "User\tUID\tHome"} \
    {print $1"\t"$3"\t"$6} END{print "Total "NR" lines."}' /etc/passwd
    User    UID     Home
    root    0       /root
    bin     1       /bin
    daemon  2       /sbin
    adm     3       /var/adm
    lp      4       /var/spool/lpd
    sync    5       /sbin
    .. ..
    iamkiller       1234    /opt/.private/iamkiller
    nsd001  0       /home/nsd001
    nsd002  1236    /home/nsd002
    nsd003  1237    /home/nsd003
    postfix 89      /var/spool/postfix
    Total 67 lines.

二、awk处理条件

目标:

本案例要求使用awk工具完成下列过滤任务,注意awk处理条件的设置:

1> 列出UID间于501~505的用户详细信息
    2> 输出/etc/hosts文件内以127或192开头的记录
    3> 列出100以内整数中7的倍数或是含7的数

步骤:

步骤一:认识awk处理条件的设置

创建测试文件passwd.txt文件:

[root@svr5 ~]# head -7 /etc/passwd > passwd.txt
    [root@svr5 ~]# cat passwd.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

1)使用正则表达式设置条件

输出其中以bash结尾的完整记录:

[root@svr5 ~]# awk -F: '/bash$/{print}' passwd.txt
    root:x:0:0:root:/root:/bin/bash

输出以a、b、c或d开头的用户名、宿主目录:

[root@svr5 ~]# awk -F: '/^[a-d]/{print $1,$6}' passwd.txt
    bin /bin
    daemon /sbin
    adm /var/adm

输出其中用户名以a开头、登录Shell以nologin结尾的用户名、登录Shell:

[root@svr5 ~]# awk -F: '/^a|nologin$/{print $1,$7}' passwd.txt
    bin /sbin/nologin
    daemon /sbin/nologin
    adm /sbin/nologin
    lp /sbin/nologin

输出其中宿主目录以bin结尾(对第6个字段做~匹配)的用户名、宿主目录信息:

[root@svr5 ~]# awk -F: '$6~/bin$/{print $1,$6}' passwd.txt
    bin /bin
    daemon /sbin
    sync /sbin
    shutdown /sbin

输出其中登录Shell不以nologin结尾(对第7个字段做!~反向匹配)的用户名、登录Shell信息:

[root@svr5 ~]# awk -F: '$7!~/nologin$/{print $1,$7}' passwd.txt
    root /bin/bash
    sync /bin/sync
    shutdown /sbin/shutdown

2)使用数值/字符串比较设置条件

输出第3行(行号NR等于3)的用户记录:

[root@svr5 ~]# awk -F: 'NR==3{print}' passwd.txt
    daemon:x:2:2:daemon:/sbin:/sbin/nologin

输出奇数行(行号NR除以2余数为1)的用户记录:

[root@svr5 ~]# awk -F: 'NR%2==1{print}' passwd.txt
    root:x:0:0:root:/root:/bin/bash
    daemon:x:2:2:daemon:/sbin:/sbin/nologin
    lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
    shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown

输出偶数行(行号NR除以2余数为0)的用户记录:

[root@svr5 ~]# awk -F: 'NR%2==0{print}' passwd.txt
    bin:x:1:1:bin:/bin:/sbin/nologin
    adm:x:3:4:adm:/var/adm:/sbin/nologin
    sync:x:5:0:sync:/sbin:/bin/sync

输出前3行文本:

[root@svr5 ~]# awk -F: 'NR<=3{print}' passwd.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

输出从第5行开始到文件末尾的所有行:

[root@svr5 ~]# awk -F: 'NR>=5{print}' passwd.txt
    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

输出用户名为“sync”的行:

[root@svr5 ~]# awk -F: '$1=="sync"{print}' passwd.txt
    sync:x:5:0:sync:/sbin:/bin/sync

输出当前用户的用户名、宿主目录、登录Shell信息:

[root@svr5 ~]# awk -F: '$1==ENVIRON["USER"]{print $1,$6,$7}' passwd.txt
    root /root /bin/bash

3)逻辑测试条件

输出第3~5行文本:

[root@svr5 ~]# awk -F: 'NR>=3&&NR<=5{print}' passwd.txt
    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

严谨一点可以写成:

[root@svr5 ~]# awk -F: '(NR>=3)&&(NR<=5){print}' passwd.txt
    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

输出第3行和第5行文本:

[root@svr5 ~]# awk -F: 'NR==3||NR==5{print}' passwd.txt
    daemon:x:2:2:daemon:/sbin:/sbin/nologin
    lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

输出“登录Shell不以nologin结尾”或者“用户名以a或d开头”的文本:

[root@svr5 ~]# awk -F: '$7!~/nologin$/||$1~/^[ad]/{print}' passwd.txt
    root:x:0:0:root:/root:/bin/bash
    daemon:x:2:2:daemon:/sbin:/sbin/nologin
    adm:x:3:4:adm:/var/adm:/sbin/nologin
    sync:x:5:0:sync:/sbin:/bin/sync
    shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown

输出UID小于3或者UID是偶数的用户记录:

[root@svr5 ~]# awk -F: '$3<3||$3%2==0{print}' passwd.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
    lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
    shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown

4)数学运算

以统计passwd.txt文件中以“:”分隔的总字段个数,需要每处理一行时将当前行的字段数(内置变量NF)计和,因此可在BEGIN时定义一个初始变量,过程称求和,最后在END时输出结果。

相关操作及结果如下(共49个字段):

[root@svr5 ~]# awk -F: 'BEGIN{x=0}\
     {x+=NF} END{print "Total "x" fields."}' passwd.txt
    Total 49 fields.

步骤二:完成任务要求的awk过滤操作

1)列出UID间于501~505的用户详细信息:

[root@svr5 ~]# awk -F: '$3>=501&&$3<=505{print}' /etc/passwd
    hunter:x:501:501::/home/hunter:/bin/bash
    vina:x:502:502::/home/vina:/bin/bash
    kdev:x:503:503::/home/kdev:/bin/bash
    zengye:x:504:504::/home/zengye:/bin/bash
    stu01:x:505:1201::/tech/nsdhome/stu01:/bin/bash

2)输出/etc/hosts映射文件内以127或者192开头的记录:

[root@svr5 ~]# awk -F: '/^127|^192/{print}' /etc/hosts
    127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
    192.168.4.5  svr5.tarena.com svr5

3)列出100以内整数中7的倍数或是含7的数:

此操作无处理文件,正常思路应该是用Shell循环来完成;因为要求用awk来实现,如果不用循环,则根据逐行处理的思路,应该提供一个100行的文本对象,然后将行号作为处理的整数,逐个判断并输出即可。

利用seq命令可生成1-100的整数序列,比如:

[root@svr5 ~]# seq 100
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    .. ..

结合管道交给awk处理,可以简化实现步骤。针对本任务而言,行号与每行的实际文本值是一致的,那么根据NR或者$0行值进行判断都是可以的。输出100以内7的倍数或是包含7的数:

[root@svr5 ~]# seq 100 | awk 'NR%7==0||NR~/7/{print}'
    7
    14
    17
    21
    27
    28
    35
    37
    42
    47
    .. ..

或者:

[root@svr5 ~]# seq 100 | awk '$0%7==0||$0~/7/{print}'
    7
    14
    17
    21
    27
    28
    35
    37
    42
    47
    .. ..

三、awk综合脚本应用

目标:

本案例要求编写脚本getupwd-awk.sh,实现以下需求:

1> 找到使用bash作登录Shell的本地用户
    2> 列出这些用户的shadow密码记录
    3> 按每行“用户名 --> 密码记录”保存到getupwd.log,如下图所示

步骤:

步骤一:任务需求及思路分析

编写getupwd-awk.sh脚本的任务要求如下:

  • 分析出使用bash作登录Shell的本地用户
  • 列出这些用户的shadow密码记录
  • 按每行“用户名 -- 密码记录”保存结果

步骤二:根据实现思路编写脚本

复制原getupwd.sh脚本,生成getupwd-awk.sh:

[root@svr5 ~]# cat getupwd.sh                      //确认原脚本内容
    #/bin/bash
    > /tmp/getupwd.log                                     ## 创建空文件
    sed -n '/:\/bin\/bash$/w /tmp/urec.tmp' /etc/passwd      ## 提取符合条件的账号记录
    UNUM=$(egrep -c '.' /tmp/urec.tmp)                   ## 取得记录个数
    while [ ${i:=1} -le $UNUM ]                         ## 从第1行开始,遍历账号记录
    do
        UREC=$(sed -n "${i}p" /tmp/urec.tmp)              ## 取指定行数的记录
        NAME=${UREC%%:*}                                 ## 截取用户名(记录去尾)
        PREC=$(sed -n "/^$NAME:/p" /etc/shadow)          ## 查找与用户名对应的密码记录
        PASS=${PREC#*:}                                  ## 掐头
        PASS=${PASS%%:*}                                ## 去尾,只留下密码记录
        echo "$NAME --> $PASS" >> /tmp/getupwd.log         ## 保存结果
        let i++                                           ## 自增1,转下一次循环
    done
    /bin/rm -rf /tmp/urec.tmp                           ## 删除临时文件
    echo "用户分析完毕,请查阅文件 /tmp/getupwd.log"         ## 完成后提示
    [root@svr5 ~]# cp getupwd.sh getupwd-awk.sh          //复制为新脚本文件

修改新脚本文件,内容参考如下:

[root@svr5 ~]# vim getupwd-awk.sh
    #/bin/bash
    ## 创建空文件
    > /tmp/getupwd.log
    ## 提取用户名列表
    awk -F: '/:\/bin\/bash$/{print $1}' /etc/passwd > /tmp/users.tmp
    ## 通过for循环遍历用户名、查询密码记录,保存结果
    for NAME in $(cat /tmp/users.tmp)
    do
        grep "^$NAME:" /etc/shadow | awk -F: '{print $1" --> "$2 | \
        "cat >> /tmp/getupwd.log"}' /etc/shadow
    done
    echo "用户分析完毕,请查阅文件 /tmp/getupwd.log" ## 完成后提示
    [root@svr5 ~]# chmod +x getupwd-awk.sh

步骤三:验证、测试脚本

[root@svr5 ~]# ./getupwd-awk.sh      
    用户分析完毕,请查阅文件 /tmp/getupwd.log
    [root@svr5 ~]# head -5 /tmp/getupwd.log
    root --> $6$IWgMYmRACwdbfwBo$dr8Yn983nswiJVw0dTMjzbDvSLeCd1GMYjbvsDiFEkL8jnXOLcocBQypOCr4C6BRxNowIxjh6U2qeFU0u1LST/
    zengye --> $6$Qb37LOdzRl5995PI$L0zTOgnhGz8ihWkW81J.5XhPp/l7x2./Me2ag0S8tRndCBL9nIjHIKkUKulHxJ6TXyHYmffbVgUT6pbSwf8O71
    clamav --> !!
    mysql --> !!
    abc --> !!
    .. ..

四、awk流程控制

目标:

本案例要求了解awk的流程控制操作,可自行设置awk语句来有验证以下操作:

1> if分支结构(双分支、多分支)
     2> while循环结构
     3> break、continue等其他控制语句

步骤:

步骤一:awk过滤中的if分支结构

1)单分支

统计/etc/passwd文件中UID小于或等于500的用户个数:

[root@svr5 ~]# awk -F: 'BEGIN{i=0}{if($3<=500){i++}}END{print i}' /etc/passwd
    39

统计/etc/passwd文件中UID大于500的用户个数:

[root@svr5 ~]# awk -F: 'BEGIN{i=0}{if($3>500){i++}}END{print i}' /etc/passwd
    28

统计/etc/passwd文件中登录Shell是“/bin/bash”的用户个数:

[root@svr5 ~]# awk -F: 'BEGIN{i=0}{if($7~/bash$/){i++}}END{print i}'\
     /etc/passwd
    29

统计/etc/passwd文件中登录Shell不是“/bin/bash”的用户个数:

[root@svr5 ~]# awk -F: 'BEGIN{i=0}{if($7!~/bash$/){i++}}END{print i}'\
     /etc/passwd
    38

2)双分支

分别统计/etc/passwd文件中UID小于或等于500、UID大于500的用户个数:

[root@svr5 ~]# awk -F: 'BEGIN{i=0;j=0}{if($3<=500){i++}else{j++}}END{print i,j}' /etc/passwd
    39 28

分别统计/etc/passwd文件中登录Shell是“/bin/bash”、 登录Shell不是“/bin/bash”的用户个数:

[root@svr5 ~]# awk -F: 'BEGIN{i=0;j=0}{if($7~/bash$/){i++}else{j++}}\
    END{print i,j}' /etc/passwd
    29 38

3)多分支

分别统计/etc/passwd文件中登录Shell是“/bin/bash”、“/sbin/nologin”、其他的用户个数:

[root@svr5 ~]# awk -F: 'BEGIN{i=0;j=0;k=0}{if($7~/bash$/){i++}\
    else if($7~/nologin$/){j++}else{k++}}END{print i,j,k}' /etc/passwd
    29 33 5

步骤二:awk过滤中的while循环结构

1)while循环

统计/etc/passwd文件内“root”出现的次数。

—— 分析:以“:”或“/”做分隔,针对每一行的每一列进行比对,如果包含“root”,则次数加1。其中,逐行处理直接由awk完成,逐列处理交给while循环,通过i变量依次取$1、$2、……、$NF进行检查;变量j在预处理时赋值0,没匹配一个字段加1。

[root@svr5 ~]# awk -F [:/] \
    'BEGIN{j=0}\
    {i=1}{while(i<=NF){if($i~/root/){j++};i++}}\
    END{print j}'  /etc/passwd
    4

此例仅为说明while循环的用法。

实际应用时,上述操作可以简单处理,可通过命令替换将文件内容赋值给一个变量(变为一行文本),然后针对此变量值以目标字符串“root”作为分隔,获取总字段数-1即可得目标字符串的总数量:

[root@svr5 ~]# echo $(cat /etc/passwd) | awk -F "root" '{print NF-1}'
    4

五、awk扩展应用

目标:

本案例要求使用awk工具完成下列两个任务:

  • 分析Web日志的访问量排名,要求获得客户机的地址、访问次数,并且按照访问次数排名

方案:

1)awk统计Web访问排名

在分析Web日志文件时,每条访问记录的第一列就是客户机的IP地址,其中会有很多重复的IP地址。因此只用awk提取出这一列是不够的,还需要统计重复记录的数量并且进行排序。

通过awk提取信息时,利用IP地址作为数组下标,每遇到一个重复值就将此数组元素递增1,最终就获得了这个IP地址出现的次数。

针对文本排序输出可以采用sort命令,相关的常见选项为-r、-n、-k。其中-n表示按数字顺序升序排列,而-r表示反序,-k可以指定按第几个字段来排序。

步骤:

步骤一:统计Web访问量排名

分步测试、验证效果如下所述。

1)提取IP地址及访问量

[root@svr5 ~]# awk  '{ip[$1]++} END{for(i in ip) {print i,ip[i]}}' /var/log/httpd/access_log
    127.0.0.1 4
    192.168.4.5 17
    192.168.4.110 13
    .. ..

2)对第1)步的结果根据访问量排名

[root@svr5 ~]# awk  '{ip[$1]++} END{for(i in ip) {print i,ip[i]}}' /var/log/httpd/access_log | sort -nr -k 2
    192.168.4.5 17
    192.168.4.110 13
    127.0.0.1 4
    .. ..

附加:

awk数据过滤软件【统计功能】;类似grep  【过滤一整行】

awk [选项] '条件{指令}'  文件
条件可以没有【默认为所有】
指令可以没有【打印整行】
不能条件指令都没有
awk默认使用空格或Tab键作为分割符

print $0      #读一行就打印当前一整行
print $1      #读一行就打印第一列
print $2      #读一行就打印第二列
...
print NR      #读一行就打印当前行的行号
print NF      #读一行就打印当前行的列数
# awk -F: '{print NR}' /etc/passwd   #读一行就打印一次当前的行号
# awk -F: '{print NF}' /etc/passwd   #读一行就打印当前行所有的列数
# awk -F: '{print $NF}' /etc/passwd   #读一行就打印当前行最后一列

打印常量(字符串需要引号)
awk '{print "dachui"}' /etc/passwd    //这个文件有多少行就打印多少行的dachui
# awk -F: '{print "第"NR"行","有"NF"列"}' /etc/passwd   打印多少行有多少列
# awk -F: '{print "第"NR"行","有"NF"列"}' /etc/passwd|head -34|tail -1  只打印第34行有几列

awk 'BEGIN{} 条件{}  END{}' 文件         # 三个条件不一定要全有,有一个就可以
所有的指令都需要放到{}里
BEGIN{}里的指令,是在读取文件之前,执行1次
{}里的指令,在读取文件过程中执行,执行N次
END{}里的指令,是在读取文件之后,执行1次

# awk -F: 'BEGIN{print "用户名\tUID\t家目录"} {print $1"\t"$2"\t"$3} END{print "总用户 量:"NR}' /opt/a.txt
这个可以在执行这个文本之前打印BEGIN{}、END{}里面的内容

# awk 'BEGIN{x=0} /bash$/{x++} END{print x}' /etc/passwd    打印出以bash结尾的用户数量,可以登录的用户,按行读取,读一次bash结尾的数值,x加一次1
3
# awk 'BEGIN{x=0} /nologin$/{x++} END{print x}' /etc/passwd   打印出以nologin结尾的用户数量,不可以登录的用户
38
awk里面BEGIN{x=0}可以不定义,默认x值为0

-F指定分隔符
awk -F: '{print $1}' /etc/passwd   #指定':'为分隔符
awk -F, '{print $1}' /etc/passwd   #指定','为分隔符

awk '/正则/{指令}'  文件
df |awk '/\/$/{print $4}'  #打印以/结尾的行的第四列

查看远程登录本机日志
# tailf /var/log/srcure

过滤查看正在占用的内存
# awk '/Failed/{print $11}' /var/log/secure    #过滤出尝试破解密码的IP地址
# free |awk '/Mem/{print $3}'

过滤查看正在占用的CPU使用率[1分钟,5分钟,15分钟]
# uptime
 20:43:58 up 24 min,  3 users,  load average: 0.00, 0.03, 0.09
# uptime |awk '{print $10}'      #打印5分钟的cpu使用率
0.03,

awk [选项] '条件{指令}'  文件

条件:
1、/正则/  awk '/root/' /etc/passwd

# awk -F: '/root/' /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin

# awk -F: '$1~/root/' /etc/passwd    #~表示正则匹配,$1表示第一列,匹配第一列里面有root的行,打印出来
root:x:0:0:root:/root:/bin/bash

# awk -F: '$7!~/bash$/' /etc/passwd   #!~表示正则匹配第7列不是以bash结尾的行,打印出来
# awk -F: '$7~/bash$/{print $1}' /etc/passwd  #表示将passwd里面能登录的用户,打印出来

2、字串和数字比较==、!=、<、<=、>、>=   (精确匹配)
awk -F:'$1=="root"'  /etc/passwd  #将root用户打印出来
awk -F:'$3<=10'  /etc/passwd      #将UID小于等于10的用户打印出来,UID<=1000即系统用户
# awk -F: '$3<=10' /etc/passwd    #将UID大于等于1000的用户打印出来,UID>=1000即普通用户
# awk 'NR==2{print}' /etc/passwd  #输出第2行文本
# awk 'NF>=6{print}' /etc/passwd  #输出列数大于或等于6的行
# awk '$2!="XX"{print}' /etc/passwd  #输出第2行文本不是XX的行
# awk '/^(127|192)/' /etc/hosts    #输出开头是127或192开头的行

3、逻辑判断&& ||
# awk -F: '$3>10 && $3<20' /etc/passwd
# awk -F: '$3==0 || $3==1000' /etc/passwd

4、算术运算
   能被7整除或包含7的数(1--200)
# seq 200|awk '$1%7==0 || $1~/7/'    #$1~/7/用到正则模糊匹配,这个数列只有1列所以是$1,匹配含有7的选项

awk 'BEGIN{x=0;print x%8}'
awk 'BEGIN{x=0;print x+8}'
awk 'BEGIN{x=0;print x-8}'
awk 'BEGIN{x=0;print x*8}'
awk 'BEGIN{x=0;print x/8}'

awk 支持if语句
if (判断){指令}
if (判断){指令}else {指令}
if (判断){指令}else if (){指令}

统计系统用户和普通用户分别是多少(1000)
awk -F: '{} END{print x,y}' /etc/passwd   #这里可以将if条件句分出来写,然后再复制进去,以防止括号太多导致错误
if($3>=1000){x++}else{y++}
最终结果:awk -F: '{if ($3>=1000){x++} else{y++}} END{print x,y}' /etc/passwd

正则:
      /正则/                对整行匹配
   $n~/正则/           对某一列匹配
   $1~/root/     对第一列匹配是否包含root

Shell基础(六):使用awk提取文本、awk处理条件、awk综合脚本应用、awk流程控制、awk扩展应用的更多相关文章

  1. Shell脚本的基本流程控制

    if else read -p '请输入分数:' score if [ $score -lt 60 ]; then echo '60分以下' elif  [ $score -lt 70 ]; then ...

  2. Shell脚本编写4-----Shell 流程控制

    没啥好说的,直接从demo里看吧!(1) if 语句shell脚本的if语句格式如下: 判断输入两个参数的大小,执行结果如下 (2)for 循环for循环语法格式如下: 执行结果如下 (3)while ...

  3. MySQL数据库(六)-- SQL注入攻击、视图、事物、存储过程、流程控制

    一.SQL注入攻击 1.什么是SQL注入攻击 一些了解sql语法的用户,可以输入一些关键字 或合法sql,来导致原始的sql逻辑发生变化,从而跳过登录验证 或者 删除数据库 import pymysq ...

  4. MySQL数据库(六) —— SQL注入攻击、视图、事物、存储过程、流程控制

    SQL注入攻击.视图.事物.存储过程.流程控制 一.SQL注入攻击 1.什么是SQL注入攻击 import pymysql conn = pymysql.Connect( user="roo ...

  5. 12、Linux基础--挂载磁盘步骤、流处理工具awk(正则 比较 逻辑 算数表达式 流程控制)

    笔记 1.晨考 1.用两种方法,实现将文件中的以# 开头的行把# 去掉 sed -r 's/^#//g' /etc/fstab cat /etc/fstab | tr -d '^#' 2.将文件中的H ...

  6. shell基础(转)

    shell基础1:文件安全与权限 http://bbs.chinaunix.net/forum/viewtopic.php?t=434579&highlight=wingger 附:Linux ...

  7. 『忘了再学』Shell基础 — 28、AWK中条件表达式说明

    目录 1.AWK的条件表达 2.条件表达式说明 (1)BEGIN (2)END (3)关系运算符 (4)说明AWK中条件表达式的执行过程 (5)AWK中使用正则表达式 (6)A~B练习 1.AWK的条 ...

  8. 『忘了再学』Shell基础 — 29、AWK内置变量

    目录 1.AWK内置变量 2.练习说明 (1)$n变量练习 (2)FS变量练习 (3)NF变量和NR变量练习 3.总结: 1.AWK内置变量 AWK内置变量如下表: awk内置变量 作用 $0 代表目 ...

  9. shell脚本之使用sed和awk进行文本处理

    Shell这种脚本语言特点是,结果松散,场景复杂,针对于一些参数都有特殊意义.针对于大部分工程师而言,使用中的情况是你可能会经常忘记参数或其意义,使你不得不查阅man或网上寻求帮助.此篇文档作用就是在 ...

随机推荐

  1. Tomcat是否关闭 maxEntriesLocalHeap

    EHCache does not allow attribute "maxEntriesLocalHeap". 这个错误是由于这个属性不支持2.5以下版本 故更新ehcache版本 ...

  2. SQL Ssever 安装.NET3.5 框架

    SQL Ssever 安装.NET3.5 框架 我们在安装 SQL Sever 2014 的时候必须要安装 .NET3.5 框架,然后才能继续安装 SQL Server 2014. 您可能在安装 SQ ...

  3. spring的 onApplicationEvent方法被执行两次问题

    原文地址:http://www.cnblogs.com/a757956132/p/5039438.html 在做web项目开发中,尤其是企业级应用开发的时候,往往会在工程启动的时候做许多的前置检查. ...

  4. apue 第4章 文件和目录

    获取文件属性 #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> int stat(c ...

  5. Windows最值得安装的小众软件

    用电脑这么久,也琢磨出自己的一些使用心得.今天和大家分享几个Windows效率工具.数量不多,但每个都是精品. ▌软件下载-卫星公众好「悦享软件」,在后台会话框中回复关键字:h108 1.Ditto ...

  6. Maven进行自动构建

    一个很常见的错误就是路径问题,要把jdk放到java工程的路径里,之前一直默认是jre https://blog.csdn.net/lslk9898/article/details/73836745  ...

  7. Python基础(二):斐波那契数列、模拟cp操作、生成8位随机密码

    一.斐波那契数列 目标: 编写fib.py脚本,主要要求如下: 输出具有10个数字的斐波那契数列 使用for循环和range函数完成 改进程序,要求用户输入一个数字,可以生成用户需要长度的斐波那契数列 ...

  8. sql查询50题

    一个项目涉及到的50个Sql语句问题及描述:--1.学生表Student(S#,Sname,Sage,Ssex) --S# 学生编号,Sname 学生姓名,Sage 出生年月,Ssex 学生性别--2 ...

  9. mysql添加索引和sql分析

    mysql索引操作 查看索引 show indexes from students; #students为表名 mysql添加索引命令 创建索引 .PRIMARY KEY(主键索引) mysql> ...

  10. JavaScript 工作原理之十一-渲染引擎及性能优化小技巧

    原文请查阅这里,略有删减,本文采用知识共享署名 4.0 国际许可协议共享,BY Troland. 本系列持续更新中,Github 地址请查阅这里. 这是 JavaScript 工作原理的第十一章. 迄 ...