`
xitong
  • 浏览: 6205068 次
文章分类
社区版块
存档分类
最新评论

awk学习笔记(实时更新ing ...)

 
阅读更多

前言

年前杂事比较多一些,特别涉及到对一些日志文本的分析,早就知道awk是这方面处理的神器,在写恶心的php间隙学习一下,虽然我觉得自己的php写的非常规范了,但是那种哦敢调用api、调用扩展的方式还是让我觉得恶心,虽然很方便,话不多说,开始awk学习,可能会分阶段完成这篇文章,有时间就记录一些吧

awk程序设计模型

awk程序是由所谓的主输入(main input)循环组成的。一个循环是一个例程,它将一直重复执行直到有一些存在的条件终止它。你不必写这个循环,它是现成的,它作为一个框架存在,在这个框架中编写的代码能够执行。
主输入循环执行的行数和输入的行数相同。
awk允许你编写两个特殊的例程,他们在任何输入被读取前和所有输入被读取后执行。他们是BEGIN和END规则相关的过程。换句话说,在主输入循环前和主输入循环之后你可以做一些处理。

awk脚本可以分为3个部分:

  • 处理输入前的将做的处理
  • 处理输入过程中将做的处理
  • 处理输入完成后做的处理

awk工作流程:

  • 自动从指定的数据文件中读取一个数据行
  • 自动更新相关的内建变量之值。如:NF,NR,$0,$1,..
  • 依次执行程序中所有的Pattern{Actions}指令。
  • 当执行完程序中所有Pattern{Actions}时,若数据文件中还有未读取的数据,则反复执行上述步骤(awk的程序设计模型决定)

执行awk

awk 'awk程序'  处理文件名

处理文件中包含多少行,awk程序就执行多少次,这是由awk程序设计模型决定的!(ps:处理文件为空,则awk不执行,很多初学者测试时容易犯这种错误,比如我

awk程序的主要结构

awk程序中主要语法是Pattern{Actions},故而常见的awk程序其型态如下:
Pattern1 {Actions1}
Pattern2 {Actions2}
...
Pattern3 {Actions3}

Pattern

awk可以接受许多不同型态的Pattern.一般常使用“关系表达式(Relational expression)”来当成Pattern。
例如:
x > 65是一个Pattern,判断变量x与65的大小关系
awk提供C语言中常见的关系运算符(Relational Operators)如:
>,<,==,>=,<=,!=
此外,awk还提供了~(match)及 !~(not match)二个关系运算符

Actions

Actions是由许多awk指令构成,而awk的指令与c语言中的指令十分类似
例如:
awk的I/O指令:print,printf(),getline...
awk的流程控制指令:if(...){...}else{...},while(...){...}

awk处理Pattern{Actions}

awk会先判断该Pattern的值,若为true,则awk执行Pattern所对应的Actions。反之,若Pattern值部为true,则awk将不执行该Pattern所对应的Actions。
例如:
awk '90 > 78 {printf "hello world!\n"}' test.txt
如果test.txt不为空,肯定可以输出hello world!

awk ' 1 > 2 {printf "hello world\n"}' test.txt
就算test.txt不为空,由于Pattern 1 > 2的值为false,所以printf语句一定不会执行!


awk处理{Actions}(缺少Pattern部分)

有时语法Pattern{Actions}中,Pattern部分被省略,只剩{Actions}。这种情况下表示:awk无条件执行这个Actions

awk内建字段变量

字段变量 字段含义
$0 当前awk所读入行的内容
$1 $0上分隔符分割后第一个字段的内容
$2 $0上分隔符分割后第二个字段的内容
... 以此类推
NF(number of Fields) $0上的字段数目
NR(NUMBER OF RECORDS) awk已读入的数据行的数目


打印文件中指定字段数据

文件内容

wangzhengyi 24 linux c php cuc
chenshan 24 linux php emacs cuc
bululu 26 english computer electricity cuc

按照制定格式输出

awk中提供了与c语言类似的printf()函数,可以用这个函数控制格式输出,我强烈推荐printf(恶心的echo真的快让我受够了,我喜欢一切跟c相关的东西)

awk '{printf("name is %s,age is %d,technology has %s %s %s,study in %s\n",$1,$2,$3,$4,$5,$6)}' test

结果:
name is wangzhengyi,age is 24,technology has linux c php,study in cuc
name is chenshan,age is 24,technology has linux php emacs,study in cuc
name is bululu,age is 26,technology has english computer electricity,study in cuc


awk的流程控制语句

常见错误:

初学者开始使用流程控制语句时,都喜欢采用类似于c代码的风格,但是可能会碰到这个错误:
awk: line 1: syntax error at or near if

举例:

(1)错误代码
awk -F "^A" 'if(2 > 3) {printf("%s %d\n", $1, $2)}' test
(2)正确的类C的代码应该
awk -F "^A" '{if(2 > 3) {printf("%s %d\n", $1, $2)}}' test

注意:正确的类c风格应该多了一个括号的包围


条件判断语句(if)

格式

{
    if(表达式)
    {
        语句一;
         .......;
    }else if(表达式)
    {
        语句2;
        ........
    }else
    {
        语句3;
        ........
    }
}

测试代码




循环语句(while,for)

while格式

{
    while(表达式)
    {
        语句;
    }
}

for格式

{
    for(变量初始化; 条件; 表达式)
    {
        语句;
    }
}

{
    for(变量 in 数组)
    {
        语句;
    }
}

测试代码:



awk数组

如果写过php和shell,那对awk的数组一定不会陌生,就是awk的数组既支持下标数组,也支持关联数组.
写个测试awk数组的用例,大家看一下就好了:



awk模式匹配

awk提供了两个运算符~(match)与!~(not match),这两个模式匹配都是正则表达式的应用,注意其使用的语法即可

语法规则

若A为一字符串,B为一正则表达式
A~B 判断字符串A中是否包含能匹配B式样的子字符串
A!~B 判断字符串A中是否未包含能匹配B式样的子字符串

测试用例



$0 ~ /[0-9]*/ 这是判断每行是否包含数字的最基础的正则表达式,如果这个不懂的话建议去看正则表达式基础吧



分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics