Linux指令:AWK - 可编程流编辑器

    科技2022-08-17  159

    Table of Contents

    awk功能

    线路寻址

    预定义的awk值

    变数

    条件和循环


     

    推荐阅读:《Linux指令:sed和awk指令》


    在详细介绍了sed 之后,还很了解awk(gawk)–可编程流编辑器

    Awk帮助您处理结构化数据并生成报告。awk实际上是一种编程语言,其语法类似于C。awk使用三个“块”指令:BEGIN,主循环和END,并且它使用与sed相似的行寻址原理

     

    awk功能


    将文本文件视为一系列记录的能力变数算术(也是浮点数)和字符串运算符循环和条件生成格式化的报告定义功能直接从脚本执行UNIX命令直接处理UNIX命令的输出处理命令行参数处理多个输入流

    编程模型

    在awk中使用了三个“块”指令:

    BEGIN,在读取第一条输入行之前执行对输入的每一行执行的主循环读取最后一条输入行后执行ENDBEGIN和END过程是可选的

    每个输入行都被视为一条记录,称为$ 0,每个单词(由空格或制表符分隔)都被视为一个字段。使用“ $”来引用字段($ 1 –第一个字段,$ 2 –第二,依此类推)。

    简单的例子:

    # cat emp avi 1200 haifa dani 2300 tel aviv rina 3100 aco # awk '{ print $1,"-",$3 }' emp avi - haifa dani - tel rina - aco

    简单打印文件:

    awk ' { print } ' filename

    使用BEGIN和END:

    # awk 'BEGIN { print "Customers List:\n==="} { print } END { print "====\nnum:" NR }' emp Customers List: === avi 1200 haifa dani 2300 tel aviv rina 3100 aco ==== num:3

    编写脚本:

    #!/usr/bin/awk -f { print $1,"-",$3 }

    运行:

    # simp emp avi - haifa dani - tel rina - aco

    带块脚本

    #! /usr/bin/awk -f BEGIN { print "Customers List:" print "===============" } { print NR , "-" ,$0 } END { print "=========" print "num:" NR }

    运行:

    # ./simple emp Customers List: =============== 1 - avi 1200 haifa 2 - dani 2300 tel aviv 3 - rina 3100 aco ========= num:3

    注意使用NR的行号。

     

    线路寻址

    可以将命令限制为带有模式的行

    #!/usr/bin/awk -f BEGIN { print "Header" } /[0-9]+/ { print "Found Number" } /[A-Za-z]+/ { print "Found Word" } /^$/ { print "Found Blank line" } END { print "Footer" }

    用它:

    # cat ./uselinead hello 100 233 bye hi 20 # ./linead uselinead Header Found Number Found Word Found Number Found Word Found Blank line Found Word Found Blank line Found Number Footer

    预定义的awk值

    FS –字段分隔符–默认空格和制表符OFS –输出字段分隔符–默认空间RS –记录分隔符–默认换行符ORS –输出记录分隔符–默认换行符OFMT –输出格式–默认为“%.6g”

    常数:

    NF –字段数,即特定行上的单词数NR –记录数,即到目前为止读取的行数FILENAME –当前正在处理的文件的名称FNR –当前文件中的当前行号(仅nawk)

    范例:

    用例

    #!/usr/bin/awk -f BEGIN{ FS=","} {print $3,$2}

    useemp2

    #!/usr/bin/awk -f BEGIN{ FS=","; OFS="*"} {print $3,$2}

    运行

    # cat ./emp2 avi,1200,haifa dani,2300,tel aviv rina,3100,aco # ./useemp emp2 haifa 1200 tel aviv 2300 aco 3100 # ./useemp2 emp2 haifa*1200 tel aviv*2300 aco*3100

     

    变数

    没有声明变量,只是给定名称和值。未初始化的变量设置为零。类型基于分配(字符串,数字)

    示例–计算文件大小的总和:

    #!/usr/bin/awk -f { print; numfiles=numfiles + 1; numbytes=numbytes + $5 } END { print numfiles, "files,", numbytes, "bytes" }

    使用管道运行它:

    ls -l | ./calcsize total 56 -rw-rw-r-- 1 developer developer 187 אוג 16 2017 avg -rwxrwxr-x 1 developer developer 310 אוג 16 2017 avg.awk -rwxrwxr-x 1 developer developer 117 אוג 16 2017 calcsize -rwxrwxr-x 1 developer developer 382 אוג 14 2017 checkops -rw-rw-r-- 1 developer developer 48 אוג 16 2017 emp -rw-rw-r-- 1 developer developer 48 פבר 16 09:39 emp2 -rwxrwxr-x 1 developer developer 198 פבר 16 09:24 linead -rw-rw-r-- 1 developer developer 254 אוג 14 2017 oplist -rwxrwxr-x 1 developer developer 154 פבר 16 09:16 simple -rwxrwxr-x 1 developer developer 148 אוג 16 2017 simple2 -rwxrwxr-x 1 developer developer 49 פבר 16 09:37 useemp -rwxrwxr-x 1 developer developer 41 פבר 16 08:47 useemp1 -rwxrwxr-x 1 developer developer 57 פבר 16 09:37 useemp2 -rw-rw-r-- 1 developer developer 26 פבר 16 09:25 uselinead 15 files, 2019 bytes

    另一个例子

    给定以下文件:

    Name CM Ph Cmp Math avi levy 68 72 91 73 eli cohen 31 59 73 87 bibi netanyahu 83 80 89 61 donald tramp 53 72 78 93 Julia roberts 69 68 79 89

    和awk脚本:

    #!/usr/bin/awk -f BEGIN { print "grades report" print "=============" } NR == 1 { next } { lines++; fullname = $1 " " $2 print fullname, ($3 + $4 + $5 + $6) / 4 sum1 += $3; sum2 += $4; sum3 += $5; sum4 += $6 } END { print "" print "Totals" print "======" print sum1/lines, sum2/lines, sum3/lines, sum4/lines }

    运行:

    # ./avg.awk ./avg grades report ============= avi levy 76 eli cohen 62.5 bibi netanyahu 78.25 donald tramp 74 Julia roberts 76.25 Totals ====== 60.8 70.2 82 80.6

     

    条件和循环

    语法类似于C

    给定以下输入文件:

    # Year : Month : Day : Customer : D / W : Amount 2015:11:9:Joe:W:5.00 2015:11:12:Mary:W:5.50 2015:12:10:Joe:W:10.00 2015:12:15:Mary:W:10.00 2016:1:2:Hank:W:35.00 2016:1:31:David:D:100.00

    使用循环和条件:

    #! /usr/bin/awk -f # Year : Month : Day : Recipient : D / W : Amount BEGIN { FS = ":" } # skip lines started with # /^[#]/ { next } # simple conditions $5 == "W" { withdrawals[$4] += $6 } $5 == "D" { deposits[$4] += $6 } END { print "Deposit totals:" for (i in deposits) printf("\t%s: $%g\n", i, deposits[i]) print "" print "Withdrawal totals:" for (i in withdrawals) if(withdrawals[i] > 15) printf("\t%s: $%g\n", i, withdrawals[i]) }

    运行:

    # ./checkops ./oplist Deposit totals: David: $100 Withdrawal totals: Hank: $35 Mary: $15.5

     

    Processed: 0.040, SQL: 9