awk 入门介绍

来源:互联网 发布:mac移动硬盘加密软件 编辑:程序博客网 时间:2024/05/16 11:59

awk 是一种基于行,准确的说是记录(record)的pattern-action编程语言, 擅长与处理带列,准确说是域(field)的文本文件。

阅读本文可以快速入门。 最好man awk

awk   -F<分隔符> <command> filename;
awk默认以N个空格为分隔符
awk  -F:  'BEGIN {处理文件前执行的代码块} {处理文件过程中执行的代码块} END {处理文件后执行的代码块}'   filename
'BEGIN{}{}END { }'
awk  内置变量
FS   field separator,设置分隔符,等同于-F

NF   number of field 代表字段数,当前行有多少列数据

FNF first number of field

$NF  代表最后一个字段内容

NR   number of record 代表当前处理的行是第几行

FNR - File Number of Record - 当前处理的行是当前处理文件的第几行


awk 算术运算符: + - * / % ^
awk 逻辑运算符: && 逻辑与,  || 逻辑或,        !非.
awk 关系运算符:
==       等于,
!=        不等于,
>         大于,
<         小于,
>=         大于等于,  
<=         小于等于
还有两个强悍的关系符
~         匹配
!~       不匹配

为了使用关系运算符合逻辑运算符, awk 支持 if()else() 语句, for()循环语句

可以把awk 命令写成文件,然后用awk -f <awkfile> filename 来执行




----------------------------------------
1. 打印文件中的列。
----------------------------------------
字段的引用  $字段操作符;  $1代表第一列,$2代表第二列。$n以此类推;  $0代表整个输入记录;
打印第一列  awk -F: '{print $1}' /etc/passwd

例1: 打印/etc/passwd里普通用户的行
awk -F: '$3>=500 && $3!=65534 {print $0}' /etc/passwd

----------------------------------------
例2: 统计 /etc/passwd 文件中的列数
----------------------------------------
提示:awk是由上往下一行一行的扫描,类似写shell脚本时的循环语句,在这里是自动循环
思路:先定义一个变量值为0,每扫一行,就加上那一行的列数(NF),最后打印出结果;
# awk -F: 'BEGIN {a=0} {a+=NF} END {print a}' /etc/passwd
统计列数大于5的总行数
awk -F: 'BEGIN {a=0} { if(NF>5) a=a+1} END {print a}' /etc/passwd

----------------------------------------
例3:综合运算,支持浮点数。
----------------------------------------
echo | awk '{print 3+2*5}'
echo | awk '{print 3.3+2^3}'

----------------------------------------
例4:找出目录下的最大的文件和最小的文件,输出平均大小
----------------------------------------
思路: ls 有一个参数大写字母S,会把文件从大到小排序,
排序后,最大文件就是第一行(NR=1),最小文件就是最后一行,平均大小为(累计总大小/NR)
cat 1.awk
BEGIN {total=0}
{
    if(NR==2) print "max file:"  $NF, "size " $5
    total+=$5
}
END {
    print "min file:" $NF, "size " $5
    print "mean file size: " total/NR
}

----------------------------------------
例5:倒序排列文件中所有的列
----------------------------------------
cat 2.awk   // 加上分号 和 c 语言书写格式一样,或更宽松。
BEGIN{FS=":"}
{
    for(i=NF;i>0;i--)
    {
        if( i !=1 )
        {
            printf("%s%s",$i,FS);
        }
        else
        {
            printf("%s",$i);
        }
    }
    printf("\n");
}
END {
    }

----------------------------------------
例6:统计tcp 的连接状态计数
----------------------------------------
netstat -n | awk '/^tcp/ {++state[$NF]} END {for(key in state) print key,"\t",state[key]}'
当然,当你用命令行敲入时, 你可以把state, key 用简单的字符替换.
解释:
/^tcp/ 是if条件的简单写法, 如果匹配^tcp
state[$NF] 是hash 数组,
NF  -- number of field.
$NF -- 该列对应的字符串。
state[$NF] 初始值默认是0 (或空)


0 0
原创粉丝点击