本文参考的是 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
^ 匹配字符串开始
$ 匹配字符串结束
. 匹配任意字符
awk 学习笔记
最新推荐文章于 2022-12-01 15:39:43 发布
本文详细介绍了awk命令的工作原理,包括其运作流程、字符串常量、正则表达式、选项、记录和字段、关联数组、操作符、语句格式、函数以及影响输入循环的关键语句。通过实例展示了awk如何处理记录、字段、数组以及如何进行字符串匹配和文件操作。文章还探讨了awk中的多维数组、条件语句、循环语句和自定义函数,为awk的学习提供了全面的指南。
摘要由CSDN通过智能技术生成