• Awk命令


    1.Awk命令语法

    1.1 执行单个命令

    awk的基本语法:

    awk -Fs '/pattern/ {action}' input-file
    

    -F为字段分界符,如果不指定,则默认空格为分隔符

    /pattern/ 和{action}需要用单引号包起来,/pattern/是可选的,如果没有,则默认对所有行都执行action.如果指定,则只对匹配的行执行action

    例如:

    $awk -F":" '/mail/ {print $1}' /etc/passwd
    mail
    

     

    1.2 执行批量命令

    如果需要执行多个命令,则可以把多个命令放在一个文件中,然后使用-f执行。

    awk –Fs –f myscript.awk input-file
    

      

    1.3 awk命令结构

    典型的awk命令包含三部分:

    (1) BEGIN区域

    BEGIN区域只会在body区域执行前执行一次.

    BEGIN区域的语法:BEGIN {awk-commands}

    (2)body区域

    body 区域的命令每次从输入文件读取一行就会执行一次

    body区域的语法: /pattern/ {awk-commands}

    (3)END区域

    END区域会在body区域执行完后执行一次。

    END区域的语法:END {awk-commands}

    例如:

    $awk 'BGEIN {FS=":";print "------"} /mail/ {print $1} END {print "----footer----"}' /etc/passwd
    _mailman:*:78:78:Mailman
    _clamav:*:82:82:ClamAV
    _amavisd:*:83:83:AMaViS
    ----footer----
    

      

    2.awk命令

    2.1 打印命令

    默认情况下,awk 的打印命令 print(不带任何参数)会打印整行数据。

    例如:

    $awk '{print}' employee.txt
    101,Jonny Doe,CEO
    102,Jason Smith,IT Manager
    103,Raj Reddy,Sysadmin
    104,Anand Ram,Developer
    105,Jane Miller,Sales Manager
    

     

    也可以传递变量"$字段序号"作为参数,打印指定的字段。例如:

    $awk '{print $1}' employee.txt
    101,Jonny
    102,Jason
    103,Raj
    104,Anand
    105,Jane
    

    $0 表示整行, $1表示第一个字段,$n表示第n个字段。

    当然,也可以通过-F指定分隔符。例如:

    $awk -F"," '{print $2}' employee.txt
    Jonny Doe
    Jason Smith
    Raj Reddy
    Anand Ram
    Jane Miller
    

      

    2.2 模式匹配

    可以只在匹配特殊模式的行执行awk命令。例如:

    $awk -F"," '/Manager/ {print $2, $3}' employee.txt
    Jason Smith IT Manager
    Jane Miller Sales Manager
    

      

    3. awk内置变量

    awk有很多内置标量,我们可以在脚本中直接使用。

    (1)FS

    awk默认的字段分隔符是空格,现在你也知道,如果要指定字段分隔符,可以使用-F选项来指定它。

    同样的事情可以使用awk内置变量FS来完成,比如:

    $awk 'BEGIN {FS=","} /Manager/ {print $2, $3}' employee.txt
    Jason Smith IT Manager
    Jane Miller Sales Manager
    

    FS可以同时指定多个分隔符:

    例如有如下文件:

    cat employee-fs.txt
    101,John Doe:CEO%10000
    102,Jason Smith:IT Manager%5000
    103,Raj Reddy:Sysadmin%4500
    104,Anand Ram:Developer%4500
    105,Jane Miller:Sales Manager%3000

    现在要以",:%"作为分隔符,如下所示:

    awk 'BEGIN {FS="[,:%]"} {print $2,$3}' employee-fs.txt
    John Doe CEO
    Jason Smith IT Manager
    Raj Reddy Sysadmin
    Anand Ram Developer
    Jane Miller Sales Manager
    

    (2) OFS-输出字段分隔符

    FS 是输入字段分隔符,OFS 是输出字段分隔符。OFS 会被打印在输出行的连续的字段之间。

    默认情况下,awk 在输出字段中间以空格分开。例如:

    $awk -F"," 'BEGIN {OFS=":"} {print $2, $3}' employee.txt
    Jonny Doe:CEO
    Jason Smith:IT Manager
    Raj Reddy:Sysadmin
    Anand Ram:Developer
    Jane Miller:Sales Manager
    

    请注意在 print 语句中使用和不使用逗号的细微差别(打印多个变量时).当在 print 语句中 指定了逗号,awk 会使用 OFS

    (3) RS-记录分隔符

    假如有下面文件:

    101,John Doe:102,Jason Smith:103,Raj Reddy

    上面每个员工信息使用冒号分隔的,我们可以指定记录分隔符,例如:

    awk 'BEGIN {RS=":";FS=","} {print $1}' employ-one-line.txt
    101
    102
    103
    

      

    (4)ORS-输出记录分隔符

    RS输入记录分隔符,ORS是输出记录分隔符

    awk 'BEGIN {FS=",";ORS="
    ---
    "} {print $2,$3}' employee.txt
    Jonny Doe CEO
    ---
    Jason Smith IT Manager
    ---
    Raj Reddy Sysadmin
    ---
    Anand Ram Developer
    ---
    Jane Miller Sales Manager
    ---
    

    (5) NR和FNR

    NR表示当前记录所在的行号。

    FNR和NR什么区别呢?如果awk命令传入两个输入文件,NR会在第二个文件继续新增,FNR在第二个文件会从1开始记录。

    awk 'BEGIN {FS=","} {print "Emp id of record number", NR, "is", $1} END {print "Total number of records:", NR}' employee.txt
    Emp id of record number 1 is 101
    Emp id of record number 2 is 102
    Emp id of record number 3 is 103
    Emp id of record number 4 is 104
    Emp id of record number 5
    

    (6) FILENAME-当前处理的文件名

    (7) NF-表示当前行的字段数

    4.awk变量及操作符

    4.1 变量

    awk变更可以直接使用,而无需申明。如果要初始化变量,最好在BEGIN区域内执行初始化。

    awk没有数据类型的概念。

    下面看下在awk中如何使用变量:

    cat employee-sal.txt
    101,John Doe,CEO,10000
    102,Jason Smith,IT Manager,5000
    103,Raj Reddy,Sysadmin,4500
    104,Anand Ram,Developer,4500
    105,Jane Miller,Sales Manager,3000
    

      

    awk 'BEGIN {FS=",";total=0} {print $2 " salary is: " $4;total+=$4} END {print "----
    Total company salary=$" total}' employee-sal.txt
    John Doe salary is: 10000
    Jason Smith salary is: 5000
    Raj Reddy salary is: 4500
    Anand Ram salary is: 4500
    Jane Miller salary is: 3000
    ----
    Total company salary=$27000
    

      

    4.2 操作符

    (1)一元操作符

    只接受单个操作数的操作符叫做一元操作符.

    awk -F, '{print ++$4}' employee-sal.txt
    10001
    5001
    4501
    4501
    3001

    (2)算术操作符

     下面是算术操作符:

    (3) 赋值操作符

    (4) 比较操作符

    下面的例子中,如果不指定操作,awk会打印符合条件的整条记录。

    $ awk -F ',' '$5 <= 5' items.txt
    102,Refrigerator,appliance,850,2
    105,Laser Printer,Office,475,5
    

    打印编号为103的商品信息:

    $awk -F"," '$1 == 103' items.txt
    103,Mp3 Player,Audio,270,15
    

    使用&&比较两个条件

    awk -F',' '$4 < 900 && $5 <= 5 {print $2}' items.txt
    Refrigerator
    Laser Printer
    

      

    (5) 正则表达式操作符

    使用“==”时,awk精确匹配。可以使用"~"来做模糊匹配。

    例如:

    #使用"=="是精确匹配
    awk -F"," '$2 == "Tennis"' items.txt
    
    #使用"~"是模糊匹配
    awk -F"," '$2 ~ "Tennis"' items.txt
    104,Tennis Racket,Sports,190,20
    

    !~即为不匹配。

    5. awk分支和循环

    awk支持条件判断,控制程序流程。大部分条件判断语句和C语言差不多。

     5.1 if结构

    if结构语法如下:

    if(conditional-expression)
    {
          action1;
          action2;     
    } 

     如果条件为真,则会执行{}中的语句。当所有语句执行完后,awk继续执行后面的语句。

    例如:

    awk -F',' '{if (($4 >= 500 && $4 <= 1000) && ($5 <= 5)) print "Only", $5, "qty of", $2, "is available"}' items.txt
    Only 2 qty of Refrigerator is available
    

      

    5.2 if else结构

     语法:

     if (conditional-expression)
    {
         action1
    }
     else
    {
         action2
    }

    例如:

    $ cat if-else.awk
    BEGIN {
    	FS=","
    }
    {
    	if($5 <= 5) {
    		print "Buy More:Order", $2, "immediately"
    	} else {
    		print "shell More:Give discount on", $2, "immediately"
    	}
    }
    

    执行结果如下:

    $ awk -f if-else.awk items.txt
    shell More:Give discount on HD Camcorder immediately
    Buy More:Order Refrigerator immediately
    shell More:Give discount on MP3 Player immediately
    shell More:Give discount on Tennis Racket immediately
    Buy More:Order Laser Printer immediately
    

      

    5.3 while结构

     语法如下:

    while(condition)
        actions
    

    while首先检查condition, 如果为true,则执行actions, 执行完actions, 再检查condition, 如果是true, 再次执行actions, 直到condition为false, 退出循环。

    也可以使用do...while.....循环:

     do
     action
     while(condition)
    

      

    5.4 for循环

     语法:

    for(initialization;condition;increment/decrement)
    

    例如:

    echo "1 2 3 4" | awk '{ for (i=1;i<=NF;i++) total = total + $i } END { print total }'
     10

     5.5 break, continue,exit

     6.awk数组

    6.1 数组语法

     语法:

    arrayname[string]=value

    - arrayname 是数组名称

    - string 是数组索引

    - value是为数组元素赋的值

    6.2 引用数组元素

    要访问awk数组中某个特定元素,使用arrayname[idnex]即可返回该索引中的值。

    注意:如果试图访问一个不存在的数组元素,awk会自动以访问时指定的索引建立该元素,并赋予null值。

    (1)

    if(index in array-name)

    可以检测元素是否存在

    (2)

    for (var in arrayname)

    可以遍历awk数组

    var是变量名,存放数组的索引

  • 相关阅读:
    Tinkoff Challenge
    Uva 12298 超级扑克2
    BZOJ 1031 字符加密
    HDU 4944 逆序数对
    51nod 1215 数组的宽度
    LA 3126 出租车
    LA 3415 保守的老师
    51nod 1275 连续子段的差异
    Uva 11419 我是SAM
    LA 4043 最优匹配
  • 原文地址:https://www.cnblogs.com/NewMan13/p/11121901.html
Copyright © 2020-2023  润新知