awk 学习笔记


本文参考的是 ubuntu 下 gawk version 3.1.6 以及 《sed&awk》
一 . awk 简介

awk 是一种解释型(tawk除外)文本处理语言

二 . awk 如何运作

命令行参数
shell 会预处理命令行,获得命令行参数(其中包括命令名),之后启动命令并向它传递剩余的参数。
系统变量ARGV:
一个关联数组,存放命令行参数,数组下标从0到ARGC-1,ARGV[0]的值为awk
系统变量ARGC:
命令行参数的个数
ARGV 的元素不包含AWK的选项和脚本

笔者根据 awk 的 info 手册以及实际操作,臆测出 awk 的大致运作过程如下:
1 . 执行 -v 选项指定的赋值语句
2 . 编译awk脚本为某种内部形式(internal form)
3 . 执行 BEGIN 块
4 . #如果没有提供输入文件
    if(ARGC == 1)
    {
    #读取标准输入直到输入结束
    while(未读到到文件末尾)#文件指标准输入
    {
        读取下一个记录
        执行awk脚本
    }
    }
    #遍历存放命令行参数的数组ARGV
    for(i = 1; i < ARGC; i++) #ARGV[0]是awk,不作为输入文件
    {
    if(ARGV[i] 是var=val形式)
    {
        定义全局变量var的值为val
    }
    else  #作为文件名处理
    {
        if(ARGV[i] 是有效的文件名)
        {
            while(未读到文件 ARGV[i] 的末尾)
            {   
                读取下一个记录
                执行 awk 脚本
            }
        }
        else
        {
            输出错误,指出文件名ARGV[i]无效
        }
    }
    }
5 . 执行 END 块

从以上的流程可以看出:
1 . BEGIN 块中  可以获得步骤 1 中赋值语句的变量值
2 . BEGIN 块中不可以获得步骤 4 中赋值语句的变量值

读者可以观察以下脚本的运行结果:
$ touch file1 file2 'c=30' #创建三个文件
$ cat file1
1111
2222
$ cat file2
3333
4444
$ cat file3
5555
6666
$ cat 'c=30'  #文件名是赋值语句的形式
c=30
c=30
$ cat test1.awk
BEGIN{
    print "---------------------"
    print "当前在 BEGIN 块中"
    print "a=" a
    print "b=" b
    print "c=" c
    print "共有" ,  ARGC , "个命令行参数:"
    for(i = 0; i < ARGC; i++)
        print i , ARGV[i];
}
{
    if(FNR == 1)
    {
        print "---------------------"
        print "当前正处理文件" , FILENAME
        print "a=" a
        print "b=" b
        print "c=" c
    }
    print  "第" , FNR , "行", $0
}
END{
    print "---------------------"
    print "当前在 END 块中"
}
$ awk -v a=10 -f test1.awk file1 b=20 file2 c=30 file3
---------------------
当前在 BEGIN 块中      #注意到BEGIN只执行一次,而且是在输入之前
a=10                   #BEGIN块里只认识通过 -v 选项赋值的变量a
b=                     # 不认识
c=                     # 不认识
共有 6 个命令行参数:   #注意到,参数里面没有选项(-f)
0 awk                  #也没有作为脚本的文件名test1.awk
1 file1
2 b=20
3 file2
4 c=30
5 file3
---------------------
当前正处理文件 file1
a=10                   #-v 选项赋值的变量,所有文件都认识
b=                     # 读入file1之后b=20才执行,file1不认识b
c=                     # c 是谁file1也不知道
第 1 行 1111
第 2 行 2222
---------------------
当前正处理文件 file2
a=10                   #-v 选项赋值的变量,所有文件都认识
b=20                   #b=20发生之后才读入file2,所以认识b
c=                     #肯定不认识
第 1 行 3333
第 2 行 4444
---------------------
当前正处理文件 file3
a=10
b=20
c=30                   #原来,尽管当前目录下有名叫'c=30'的文件,但awk仍然把它当成赋值语句了
第 1 行 5555
第 2 行 6666
---------------------
当前在 END 块中        #注意到END发生在所有输入完毕之后
$

三 . 字符串常量
字符串常量是包括在两个双引号之间的一系列字符。
awk 能够像 C 语言一样识别字符串常量中如下转义字符:
//        字面反斜杠
/a        响铃(alert)
/b        退格键(backspace)
        作用:删除光标左边的字符并使光标左移一格
/f        进纸键(form-feed)
        作用:不清楚
/n        新行符(newline character)
/r        回车符(carriage return)
/t        水平制表符(horizontal tab)
/v        垂直制表符(vertical tab)
/xhexdigits     转义/x之后的 16 进制字符串为对应的字符
        /x1B 代表 ESC 字符
/ddd        将 一位,两位,三位的十进制数转化为对应的字符
        /033 或 /33 代表 ESC 字符
/c        字面的 字符 c

注意:
以上转义序列能够被 awk 的正则表达式识别!!


四 . 正则表达式


gawk 默认支持 POSIX ERE , GAWK 独有的转义序列, 以及 gawk 字符串常量支持的 C 类的转义序列。

POSIX ERE 支持以下形式的正则表达式:
c        匹配单个非元字符c
/c        匹配字面的元字符c
^        匹配字符串开始
$        匹配字符串结束
.        匹配任意字符

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值