awk内建变量

AWK的内建变量包括域变量,例如$1, $2, $3,以及$0。这些变量给出了记录中域的内容。 内建变量也包括一些其他变量:

  • NR:已输入记录的条数。

  • NF:当前记录中域的个数。记录中最后一个域可以以$NF的方式引用。

  • FILENAME:当前输入文件的文件名。

  • FS:“域分隔符”,用于将输入记录分割成域。其默认值为“空白字符”,即空格和制表符。FS可以替换为其它字符,从而改变域分隔符。

  • RS:当前的“记录分隔符”。默认状态下,输入的每行都被作为一个记录,因此默认记录分隔符是换行符。

  • OFS:“输出域分隔符”,即分隔print命令的参数的符号。其默认值为空格。

  • ORS:“输出记录分隔符”,即每个print命令之间的符号。其默认值为换行符。

  • OFMT:“输出数字格式”(Format for numeric output),其默认值为"%.6g"。


  1. awk脚本的结构基本如下所示:

    awk 'BEGIN { print "Start"} pattern { command } END { print "end" }' file

  2. 实战演练:

    awk 'BEGIN { statements } { statements } END {end statements}'

    awk "BEGIN { statements } { statements } END {end statements}"

    awk 'BEGIN { i=0 } { i++ } END { print i}' file

    echo |awk '{ var1="v1";var2="v2";var3="v3";print var1,var2,var3}'

    echo |awk '{ var1="v1";var2="v2";var3="v3";print var1 "-" var2 "-"var3}'

  3. awk特殊变量:

    NR:表示记录数量,执行过程中对应于当前行号。

    NF:表示字段数量,执行过程中对应于当前行的字段数。

    $0:这个变量包含执行过程中当前行的文本内容。

    $1:这个变量包含第一个字段的文本内容。

    $2:这个变量包含第二个字段的文本内容。

    echo -e "line1 f2 f3\nline2 f4 f5\nline3 f6 f7"| \
    > awk '{print "Line no:"NR",No of fields"FR,"$0="$0,"$1="$1,"$2="$2,"$3="$3}'
    Line no:1,No of fields $0=line1 f2 f3 $1=line1 $2=f2 $3=f3
    Line no:2,No of fields $0=line2 f4 f5 $1=line2 $2=f4 $3=f5
    Line no:3,No of fields $0=line3 f6 f7 $1=line3 $2=f6 $3=f7

    #打印行中最后一个字段

    awk -F":" '{ print $NF }' /etc/passwd
    awk -F":" '{ print $(NF-1) }' /etc/passwd

    seq 5 |awk 'BEGIN{sum=0;print "Summation:"} {print sum"+"$1;sum+=$1} END{print "=====\n"sum}'

  4. 将外部变量值传递给awk

    VAR=10000
    echo | awk -v VARIABLE=$VAR '{print VARIABLE}'

    var1="abc";var2="def"
    echo |awk '{print v1,v2}' v1=$var1 v2=$var2

  5. 用getline读取行

    seq 5 |awk 'BEGIN {print "Read ahead first line" ,$0} {getline;print $0}'

  6. 使用过滤模式对awk处理的行进行过滤


    打印行号小于3的行内容

    seq 5 |awk 'NR < 3 {print $0}'
    打印行号在1到4行之间的行
    seq 5 |awk 'NR==1,NR==4 {print $0}'

    打印奇数行内容

    seq 5 |awk 'NR%2 == 1 {print $0}'

    打印包含样式linux的行

    echo -e "welcome to linux.\nhello world." |awk '/linux/ {print $0}'
    打印不包含样式linux的行

    echo -e "welcome to linux.\nhello world." |awk '!/linux/ {print $0}'

  7. 设定字段定界符(分隔符),FS,OFS  

    awk -F: '{print $NF}' /etc/passwd
    awk 'BEGIN{FS=":"} {print $NF}' /etc/passwd

  8. 从awk中读取命令输出:

    “command” | getline output;

    echo |awk '{ "grep root /etc/passwd" |getline cmdout;print cmdout}'

  9. 在awk中使用循环

    for (i=0;i<10;i++) {print $i;}

    或者

    for (i in array) {print array[i];}

    echo | awk '{for(i=1;i<10;i++) print i}'

  10. awk内建的字符串控制函数

    length(string):返回字符串的长度

        echo |awk 'BEGIN{domain="sharelinux.com"}{len=length(domain);print len}'

    index(string, search_string):返回search_string在字符串中出现的位置。

       echo |awk '{indexs=index("sharelinux.com", "com");print indexs}'

    split(string,array,delimiter):用界定符生成一个字符串列表,并将该列表存入数组。

        echo |awk 'BEGIN{domain="www.sharelinux.com";split(domain,arr,".")}{print arr[1],arr[2],arr[3]}'

        echo |awk 'BEGIN{domain="www.sharelinux.com";split(domain,arr,".")}{for (i in arr) print arr[i]}'

    sub(regex,replacment_str,string):将正则表达式匹配到的第一处内容替换成replacment_str.

    gsub(regex,replacement_str,string):和sub()类似,不过该函数会替换正则表达式匹配到的所有内容。

    match(regex,string):检查正则表达式是否能够匹配字符串。如果能够匹配,返回非0值;否则,返回0,。match()有两个相关的特殊变量,分别是RSTART和RLENGTH。变量RSTART包含正则表达式所匹配内容的起始位置,而变量RLENGTH包含正则表达式所匹配内容的长度。

  11. 使用awk实现倒序输出: 

    awk '{lifo[NR]=$0}END{ for(lno=NR;lno>-1;lno--){print lifo[lno]}}' /etc/passwd


  12. 参考链接:

    http://www.gnu.org/software/gawk/manual/html_node/String-Functions.html

    http://zh.wikipedia.org/wiki/AWK