zoukankan      html  css  js  c++  java
  • linux awk 命令详解

    awk是一个非常棒的数字处理工具。相比于sed常常作用于一整行的处理,awk则比较倾向于将一行分为数个“字段”来处理。运行效率高,而且代码简单,对格式化的文本处理能力超强。

    调用awk

    有三种方式调用awk

    1.命令行方式
    awk [-F  field-separator]  'commands'  input-file(s)
    其中,commands 是真正awk命令,[-F域分隔符]是可选的。 input-file(s) 是待处理的文件。
    在awk中,文件的每一行中,由域分隔符分开的每一项称为一个域。通常,在不指名-F域分隔符的情况下,默认的域分隔符是空格。
    
    2.shell脚本方式
    将所有的awk命令插入一个文件,并使awk程序可执行,然后awk命令解释器作为脚本的首行,一遍通过键入脚本名称来调用。
    相当于shell脚本首行的:#!/bin/sh
    可以换成:#!/bin/awk
    
    3.将所有的awk命令插入一个单独文件,然后调用:
    awk -f awk-script-file input-file(s)
    其中,-f选项加载awk-script-file中的awk脚本,input-file(s)跟上面的是一样的。

    选项参数说明:

    -F fs or --field-separator fs
         指定输入文件折分隔符,fs是一个字符串或者是一个正则表达式,如-F:。
    
    -f scripfile or --file scriptfile
         从脚本文件中读取awk命令。

    Example:
    Consider the following text file as the input file for all cases below.

    $cat > employee.txt 
    ajay manager account 45000
    sunil clerk account 25000
    varun manager sales 50000
    amit manager account 47000
    tarun peon sales 15000
    deepak clerk sales 23000
    sunil peon sales 13000
    satvik director purchase 80000 

    1. Default behavior of Awk : By default Awk prints every line of data from the specified file.

    $ awk '{print}' employee.txt

    Output:

    ajay manager account 45000
    sunil clerk account 25000
    varun manager sales 50000
    amit manager account 47000
    tarun peon sales 15000
    deepak clerk sales 23000
    sunil peon sales 13000
    satvik director purchase 80000 
    

    2. Print the lines which matches with the given pattern.

    $ awk '/manager/ {print}' employee.txt 
    
    ajay manager account 45000
    varun manager sales 50000
    amit manager account 47000 
    

    3. Splitting a Line Into Fields : 

    $ awk '{print $1,$4}' employee.txt 
    
    
    ajay 45000
    sunil 25000
    varun 50000
    amit 47000
    tarun 15000
    deepak 23000
    sunil 13000
    satvik 80000 
    

      

    awk内置变量

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

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

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

    Examples:

    Use of NR built-in variables (Display Line Number)

    $ awk '{print NR,$0}' employee.txt 
    
    1 ajay manager account 45000
    2 sunil clerk account 25000
    3 varun manager sales 50000
    4 amit manager account 47000
    5 tarun peon sales 15000
    6 deepak clerk sales 23000
    7 sunil peon sales 13000
    8 satvik director purchase 80000 
    

      

    Use of NF built-in variables (Display Last Field)

    $ awk '{print $1,$NF}' employee.txt 
    
    
    ajay 45000
    sunil 25000
    varun 50000
    amit 47000
    tarun 15000
    deepak 23000
    sunil 13000
    satvik 80000 
    

     

    Another use of NR built-in variables (Display Line From 3 to 6)

    $ awk 'NR==3, NR==6 {print NR,$0}' employee.txt 
    
    
    3 varun manager sales 50000
    4 amit manager account 47000
    5 tarun peon sales 15000
    6 deepak clerk sales 23000 
    

      

      

    awk编程

     变量和赋值

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

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

    awk '{count++;print $0;} END{print "user count is ", count}' /etc/passwd
    root:x:0:0:root:/root:/bin/bash
    ......
    user count is  40
    

    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
    ...
    [end]user count is  40
    

      

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

    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
    

      

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

    条件语句

     awk中的条件语句是从C语言中借鉴来的,见如下声明方式:

    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
    ......
    

      

    这里使用for循环遍历数组

    本文摘自:

    https://cloud.tencent.com/developer/article/1200368

    https://www.geeksforgeeks.org/awk-command-unixlinux-examples/

    http://www.gnu.org/software/gawk/manual/gawk.html

  • 相关阅读:
    关于yarn的spark配置属性
    spark1.2.0编译
    sqoop1.99.4 JAVA API操作
    数据库范式(1NF 2NF 3NF BCNF)
    HTTP协议详解【转载】
    ESI 动态缓存技术[转载]
    ESI+varnish页面片段缓存
    用 Gearman 分发 PHP 应用程序的工作负载【转载】
    介绍 JSON的
    跨多种环境部署 Gearman -改善应用程序性能和降低服务器负载
  • 原文地址:https://www.cnblogs.com/qianyuliang/p/6634468.html
Copyright © 2011-2022 走看看