zoukankan      html  css  js  c++  java
  • awk内置变量 awk有许多内置变量用来设置环境信息,这些变量可以被改变,下面给出了最常用的一些变量。

    ARGC               命令行参数个数
    ARGV               命令行参数排列
    ENVIRON            支持队列中系统环境变量的使用
    FILENAME           awk浏览的文件名
    FNR                浏览文件的记录数
    FS                 设置输入域分隔符,等价于命令行 -F选项
    NF                 浏览记录的域的个数
    NR                 已读的记录数
    OFS                输出域分隔符
    ORS                输出记录分隔符
    RS                 控制记录分隔符

    此外,$0变量是指整条记录。$1表示当前行的第一个域,$2表示当前行的第二个域,......以此类推。

    统计/etc/passwd:文件名,每行的行号,每行的列数,对应的完整行内容:

    awk  '{print  "共"NF"列","
    共"NR"行","
    linecotent:"$0}'
    awk  -F ':'  '{print "filename:" FILENAME ",linenumber:" NR ",columns:" NF ",linecontent:"$0}' /etc/passwd
    filename:/etc/passwd,linenumber:1,columns:7,linecontent:root:x:0:0:root:/root:/bin/bash
    filename:/etc/passwd,linenumber:2,columns:7,linecontent:daemon:x:1:1:daemon:/usr/sbin:/bin/sh
    filename:/etc/passwd,linenumber:3,columns:7,linecontent:bin:x:2:2:bin:/bin:/bin/sh
    filename:/etc/passwd,linenumber:4,columns:7,linecontent:sys:x:3:3:sys:/dev:/bin/sh

    使用printf替代print,可以让代码更加简洁,易读

    awk  -F ':'  '{printf("filename:%10s,linenumber:%s,columns:%s,linecontent:%s
    ",FILENAME,NR,NF,$0)}' /etc/passwd

    print和printf

    awk中同时提供了print和printf两种打印输出的函数。

    其中print函数的参数可以是变量、数值或者字符串。字符串必须用双引号引用,参数用逗号分隔。如果没有逗号,参数就串联在一起而无法区分。这里,逗号的作用与输出文件的分隔符的作用是一样的,只是后者是空格而已。

    printf函数,其用法和c语言中printf基本相似,可以格式化字符串,输出复杂时,printf更加好用,代码更易懂。

     awk编程

     变量和赋值

    除了awk的内置变量,awk还可以自定义变量。

    下面统计/etc/passwd的账户人数

     1 [root@Nginx ~]# awk '{count++;print $0;}END{print "user count is," count}' /etc/passwd
     2 root:x:0:0:root:/root:/bin/bash
     3 bin:x:1:1:bin:/bin:/sbin/nologin
     4 daemon:x:2:2:daemon:/sbin:/sbin/nologin
     5 adm:x:3:4:adm:/var/adm:/sbin/nologin
     6 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
     7 sync:x:5:0:sync:/sbin:/bin/sync
     8 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
     9 halt:x:7:0:halt:/sbin:/sbin/halt
    10 mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
    11 uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin
    12 operator:x:11:0:operator:/root:/sbin/nologin
    13 games:x:12:100:games:/usr/games:/sbin/nologin
    14 gopher:x:13:30:gopher:/var/gopher:/sbin/nologin
    15 ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
    16 nobody:x:99:99:Nobody:/:/sbin/nologin
    17 vcsa:x:69:69:virtual console memory owner:/dev:/sbin/nologin
    18 rpc:x:32:32:Rpcbind Daemon:/var/cache/rpcbind:/sbin/nologin
    19 rpcuser:x:29:29:RPC Service User:/var/lib/nfs:/sbin/nologin
    20 nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin
    21 sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
    22 saslauth:x:499:76:Saslauthd user:/var/empty/saslauth:/sbin/nologin
    23 mailnull:x:47:47::/var/spool/mqueue:/sbin/nologin
    24 smmsp:x:51:51::/var/spool/mqueue:/sbin/nologin
    25 user count is,23

    count是自定义变量。之前的action{}里都是只有一个print,其实print只是一个语句,而action{}可以有多个语句,以;号隔开。

    这里没有初始化count,虽然默认是0,但是妥当的做法还是初始化为0:

    awk 'BEGIN {count=0;print "[start]user count is ", count} {count=count+1;print $0;} END{print "[end]user count is ", count}' /etc/passwd
    [start]user count is 0
    root:x:0:0:root:/root:/bin/bash
    bin:x:1:1:bin:/bin:/sbin/nologin
    daemon:x:2:2:daemon:/sbin:/sbin/nologin
    ....
    [end]user count is 23

    统计某个文件夹下的文件占用的字节数

    ls -l |awk 'BEGIN {size=0;} {size=size+$5;} END{print "[end]size is ", size}'
    [end]size is  8657198

    如果以M为单位显示:

    ls -l |awk 'BEGIN {size=0;} {size=size+$5;} END{print "[end]size is ", size/1024/1024,"M"}' 
    [end]size is  8.25889 M

    注意,统计不包括文件夹的子目录。

    条件语句

    if (expression) {
        statement;
        statement;
        ... ...
    }
    
    if (expression) {
        statement;
    } else {
        statement2;
    }
    
    if (expression) {
        statement1;
    } else if (expression1) {
        statement2;
    } else {
        statement3;
    }

    统计某个文件夹下的文件占用的字节数,过滤4096大小的文件(一般都是文件夹):

    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"}' 
    [end]size is  8.22339 M

    循环语句

    awk中的循环语句同样借鉴于C语言,支持while、do/while、for、break、continue,这些关键字的语义和C语言中的语义完全相同。

    数组

      因为awk中数组的下标可以是数字和字母,数组的下标通常被称为关键字(key)。值和关键字都存储在内部的一张针对key/value应用hash的表格里。由于hash不是顺序存储,因此在显示数组内容时会发现,它们并不是按照你预料的顺序显示出来的。数组和变量一样,都是在使用时自动创建的,awk也同样会自动判断其存储的是数字还是字符串。一般而言,awk中的数组用来从记录中收集信息,可以用于计算总和、统计单词以及跟踪模板被匹配的次数等等。

    显示/etc/passwd的账户

    awk -F ':' 'BEGIN {count=0;} {name[count] = $1;count++;}; END{for (i = 0; i < NR; i++) print i, name[i]}' /etc/passwd
    root
    daemon
    bin
    sys
    sync
    games
    ......
  • 相关阅读:
    Leetcode 15 3Sum
    Leetcode 383 Ransom Note
    用i个点组成高度为不超过j的二叉树的数量。
    配对问题 小于10 1.3.5
    字符矩阵的旋转 镜面对称 1.2.2
    字符串统计 连续的某个字符的数量 1.1.4
    USACO twofive 没理解
    1002 All Roads Lead to Rome
    USACO 5.5.1 求矩形并的周长
    USACO 5.5.2 字符串的最小表示法
  • 原文地址:https://www.cnblogs.com/nb-blog/p/5285535.html
Copyright © 2011-2022 走看看