zoukankan      html  css  js  c++  java
  • awk用法

    原文地址: http://www.grymoire.com/Unix/Awk.html#uh-0

    基本结构:

    awk程序都是如此的一个基本结构:

    pattern { action }

    pattern指定,action是什么时候执行的。AWK是以行为导向的。pattern就是指定了,在每一个行作为输入的时候,进行一个测试。条件为真,就会采取行动。

    没人的pattern是匹配每一行。这就是blank或者是NULL pattern。除此之外的两个模式是BEGIN和END。这两个的意思是,在一个行作为输入之前或之后进行指定的动作。

    BEGIN { print "START" }
          { print         }
    END   { print "STOP"  }

    这个脚本没有什么用,但是作为修改之后,如下面:

    #!/usr/bin/awk -f
    BEGIN { print "File	Owner"}
    { print $8, "	", $3}
    END { print " - DONE -" }

      指的是一个tab

    "$8"和"$3"指的是第几个变量(输入行的域,列),和脚本差不多。

    将上面的代码保存为脚本FileOwner,并且设置可执行全县,然后使用

    ls -l | FileOwner

    还可以直接写成脚本:

    #!/bin/bash -f
    # Linux users have to change $8 to $9
    awk '
    BEGIN     { print "File	Owner" } 
            { print $8, "	", $3}    
    END       { print " - DONE -" } 
    '

    简单用法:

    如何使用变量定义列

    #!/bin/bash
    column=1
    awk '{print $'$column'}'

    默认值的用法:

    #!/bin/bash
    # Linux users have to change $8 to $9
    column=${3:-4}
    awk '{print $'$column'}'

    这节讨论以下awk的不同的语法元素:

    二元的操作符:

    OperatorTypeMeaning
    + Arithmetic Addition
    - Arithmetic Subtraction
    * Arithmetic Multiplication
    / Arithmetic Division
    % Arithmetic Modulo
    <space> String Concatenation

    使用范例如下:

    ExpressionResult
    7+3 10
    7-3 4
    7*3 21
    7/3 2.33333
    7%3 1
    7 3 73

    awk没有类型的概念。

    "123"字符串,随时回转换为数字123. "123X" 会转换为0(不同的awk有不同的定义。也有可能是123.)

    单个操作符:

    "+" and "-" operators 用于表示正负。

    自增和自减操作符

    "++" 和 "--" 行为和C语言一样。

    赋值操作符:

    variable = arithmetic_expression

    x=1+2*3 4; 的顺序 等于 x = (1 + (2 * 3)) "4";

    x=x+2; 等于 x+=2;

    类似的操作符有:

    OperatorMeaning
    += Add result to variable
    -= Subtract result from variable
    *= Multiply variable by result
    /= Divide variable by result
    %= Apply modulo to variable

    条件表达式:

    这些操作符可以用于if和while这些表达式当中:

    OperatorMeaning
    == Is equal
    != Is not equal to
    > Is greater than
    >= Is greater than or equal to
    < Is less than
    <= Is less than or equal to

    正则表达式:

    OperatorMeaning
    ~ Matches
    !~ Doesn't match

    使用例子:

    word !~ /START/
    lawrence_welk ~ /(one|two|three)/

    and/or/not

    "&&" and "||" and "!"

    awk的命令

    if ( conditional ) statement [ else statement ]
    
    while ( conditional ) statement
    
    for ( expression ; conditional ; expression ) statement
    
    for ( variable in array ) statement
    
    break
    
    continue
    
    { [ statement ] ...}
    
    variable=expression
    
    print [ expression-list ] [ > expression ]
    
    printf format [ , expression-list ] [ > expression ]
    
    next 
    
    exit

    用于打印平方(这是能够在linux上bash和gawk运行的,和原文有区别)

    #!/bin/awk -f
    BEGIN {
    
    # Print the squares from 1 to 10 the first way
    
        i=1;
        while (i <= 10) {
            printf "The square of " i " is " i*i "
    ";
            i = i+1;
        }
    
    # do it again, using more concise code
    
        for (i=1; i <= 10; i++) {
            printf "The square of " i " is " i*i "
    ";
        }
    
    # now end
    exit;
    }

    还有另外一个尝试的版本:

    #!/bin/awk -f
    BEGIN {
    
    # Print the squares from 1 to 10 the first way
    
        i=1;
        while (i <= 10) {
            print "The square of ", i ," is ", i*i, "
    ";
            i = i+1;
        }
    
    # do it again, using more concise code
    
        for (i=1; i <= 10; i++) {
            printf "The square of " i " is " i*i "
    ";
        }
    
    # now end
    exit;
    }

    在这里,第一个,我注意到 变量i 使用的时候, 就只需要打出i就可以了。

    第二个,print 可以使用逗号(,)来进行连接, printf使用空格( )来进行连接字符串。

    第二个接受一个参数,然后返回平方:

    #!/bin/awk -f
    BEGIN {
        print "type a number";
    }
    {
        print "The square of ", $1, " is ", $1*$1;
        print "type another number";
    }
    END {
        print "Done"
    }

    这个程序汇呈现循环的方式来进行的,问了一个又一个。

    结果

    type a number
    12
    The square of  12  is  144
    type another number
    22
    The square of  22  is  484
    type another number
    33
    The square of  33  is  1089
    type another number

    可以这样使用:

    $ echo 1 | ./awk.example.1.bash
    type a number
    The square of  1  is  1
    type another number

    下面是这样一个程序, 他清点所有的行数,并且把第一列的行的数加起来,并且计算平均值

    $ wc -c *
     414 awk.example.1.bash
     304 awk.example.1.bash~
      94 FileOwner
       0 FIleOwner~
     825 Makefile
    1637 total

    然后

     wc -c * | ./awk.example.1.bash
    6 lines read
    total is  3274
    average is  545.667

    awk的内置变量:

    有两种变量,第一个是用户定义的,第二个是位置变量。

    位置变量不是一个特殊的变量,而是由美元符号($)所开头的一个变量。

    因此:

    #!/bin/awk -f
    BEGIN {
    print $1; # 输出第一个位置变量
    X=1;
    print $X; # 同样也是输出第一个位置变量
    print X # 输出变量X
    }

    有一个特殊的变量: $0,所指的是输出所有awk所读入的整行

    如果你输入了8个域,在一行,就等于

    print $0;
    print $1, $2, $3, $4, $5, $6, $7, $8

    要注意,这个不要在BEGIN上面用,是没有用的哦

    #!/bin/awk -f
    BEGIN {
        print $0; # 完全每输出
    }
    {
        print $0;
    }

    你也可以修改这个域的值为空,如下

    $ wc -c * 
      40 awk.example.1.bash
     304 awk.example.1.bash~
      94 FileOwner
       0 FIleOwner~
     825 Makefile
    1263 total
    
    
    #!/bin/awk -f
    {
        $2="";
        print;
    }
    
    $ wc -c * | ./awk.example.1.bash
    77 
    304 
    94 
    0 
    825 
    1300 

    和以下对比:

     #!/bin/awk -f
    {
        print $1;
    }
    
    
    wc -c * | ./awk.example.1.bash
    32
    304
    94
    0
    825
    1255
    [andrew@andrew 2]$ 

    结果是一样的,但是不完全一样。我也不知道有什么不一样阿。

    FS 输入的分割符

    awk的-F可以用来作为分割符:

    awk -F: '{if ($2 == "") print $1 ": no password!"}' < /etc/passwd

    这个把一行根据:来进行分域。

    同样的,可以使用FS作为分割符

    #!/bin/awk -f
    BEGIN {
        FS=":";
    }
    {
        if ( $2 == "" ) {
            print $1 ": no password!";
        }
    }
    
    # 使用方法
    $ ./awk.example.1.bash < /etc/passwd

    这时候再使用-F选项是没有用的。因为直接调用了"#!/bin/awk -f"

    还有一个优点就是,可以i设置多于一个的分割符。

    # 文本
    ONE 1 I
    TWO 2 II
    #START
    THREE:3:III
    FOUR:4:IV
    FIVE:5:V
    #STOP
    SIX 6 VI
    SEVEN 7 VII
    
    
    # 处理的脚本
    #!/bin/awk -f
    {
        if ($1 == "#START") {
            FS=":";
        } else if ($1 == "#STOP") {
            FS=" ";
        } else {
            #print the Roman number in column 3
            print $3
        }
    }

    以下另外一个脚本,输出比较奇怪

    # 文本
    # One Two:Three:4 Five
    
    #!/bin/awk -f
    {
        print $2
        FS=":"
        print $2
    }
    
    # 输出:
    Two:Three:4
    Two:Three:4
    
    #!/bin/awk -f
    {
        FS=":"
        print $2
    }
    
    # 输出
    Three

    原因就是: 在读入输入之前改变FS,是有效的;在读入之后,就不会再有效了。默认FS是空格

    但是能使用这个方法来进行动态定义:

    #!/bin/awk -f
    {
        if ( $0 ~ /:/ ) {
            FS=":";
            $0=$0
        } else {
            FS=" ";
            $0=$0
        }
        #print the third field, whatever format
        print $1
    }
    
    # 输出
    One Two

    OFS 输出域的分割符

    #!/bin/awk -f
    {
        # 只会输出第一个域,这是因为,空格连接的$2和$3,然后输出的时候没有一个空格
        print $2 $3
        # 输出两个域,第二个awk会在,号中放入一个空格(默认的OFS就是空格)
        print $2, $3 
    }

    在输出的时候取消密码,可以这么做

    #!/bin/awk -f
    BEGIN {
        FS=":";
        OFS=":";
    }
    {
        $2="";
        print
    }

    getline的用法,遇到结尾的时候,返回0

    从文件中读入:

    getline < "secondary.input(文件名)"
  • 相关阅读:
    信息化与信息系统4
    信息化与信息系统3
    信息化与信息系统2
    信息化与信息系统1
    ASP.NET Core教程:ASP.NET Core 程序部署到Windows系统
    C#几种单例模式
    SQL查询优化
    动态类型dynamic(ExpandoObject)
    PV(访问量)、UV(独立访客)、IP(独立IP)
    Spring Boot 2.配置
  • 原文地址:https://www.cnblogs.com/hwy89289709/p/6837993.html
Copyright © 2011-2022 走看看