awk的惊人表现
1. awk是什么
awk是一门脚本语言,主要为了简化一般文本处理的工作,简单并且功能强大。相同功能的程序如果c或者c++来实现,结果将是程序更长,更难调试,而且执行的速度只是稍快一些而已。
2. 程序元素
2.1 注释
注释(和shell一样 以#
开头)和空白(程序中任何地方都可以有空白),单个语句不能跨行,除非用反斜杠 \
2.2 字符串
(1) awk 里面字符串常量用 引号“”作为定界符 如下所示:
foo = "hello world"
字符串中可以包含任意8-bit的字符,除了控制字符NUL(字符值为0,表示着字符串的中断,但是gawk中没有此限制,可以处理任意二进制文件)
(2) **反斜杠 \ ** 转义序列 允许非打印字符
`[jackson@localhost ~]$ echo -e "A\tZ" 这里的 -e 为:enable interpretation of backslash escapesA Z
(3)字符串的比较 (比较后返回 1 为真, 0 为假)
== != > >= < <=
(4) 由于awk没有字符串数据类型,故awk中没有特定的字符串连续运算符,两个连续字符串,会自动地连接在一起
例如:
s = "ABCD"
s = "AB" "CD"
s = "A" "BC" "D"
s = "A" "B" "C" "D"
以上四个s均为 “ABCD”
(5) 数字转化为字符串,只要通过数字连接空字符串即可
例如:
n = 123
s = "" n
字符串转换为数字,只要加个0到字符串里即可
例如:
s = "123"
n = s + 0
(6) awk对正则表达式有很好的支持:~
(匹配) !~
(不匹配)
正则表达式常量可以用 引号 “” 和 斜杠加以定界
(7) awk的数值运算符和c语言差不多,值得注意的是指数运算符 ^
和 **
(8) 标量变量(保存单一值的变量叫做标量变量) , awk就像绝大多数的脚本语言一样,变量无需先行声明
- 所有的awk变量在建立时其初始值为一个空字符串值
- 变量名字要匹配正则表达式
[A-Za-z][A-Za-z_0-9]
- awk的变量名称是和大小写有关的
- awk提供了很多内建变量
2.3 数组变量
(1) awk 允许在数组名称之后,以方括号将任意数字或字符串表达式括起来作为索引,以任意值作为索引的数组称之为关联数组
(2) 数组无须申明大小,数组的存储空间会在引用新元素时自动增长
(3) 删除元素 delete array[index]
删除整个数组 delete array
(4) awk会将以逗号分隔的索引列表看作是一个字符串
例如: maildrop[52,"Oak Lane","T4"]
awk会将索引列表转化 "53" SUBSEP "Oak Lane" SUBSEP "T4"
2.4 命令行参数
(1) awk通过内建变量 ARGC
(参数个数) ARGV
(参数向量)
例子: showargs.awk
BEGIN{
print "ARGC =", ARGC
for (k = 0; k < ARGC; k++)
print "ARGV[" k "] = [" ARGV[k] "]"
}
结果:
[jackson@localhost ~]$ awk -v one=1 -v two=2 -f showargs.awk three=3 file1 four=4 file2 file2
ARGC = 6
ARGV[0] = [awk]
ARGV[1] = [three=3]
ARGV[2] = [file1]
ARGV[3] = [four=4]
ARGV[4] = [file2]
ARGV[5] = [file2]
由上面可知:参数存储在0,1,···,ARGV-1中,第0个项目是awk程序本身,而-v
和-f
选项结合的参数是不可使用的。
2.5 环境变量
3 记录和字段
例子:
[jackson@localhost ~]$ echo ' hello jackson ' | awk -F' ' '{print NF ":" $0}'
2: hello jackson
字段分隔符可以在变量FS
中获取,默认值为单一空格,它的解释方式为:一个或多个空白字符(空格和制表符)以及行的开头和结尾空白
如果想要设置为精确的单个空白字符可以这样: awk -F'[ ]' '{print NF ":" $0}'
$0: 当前记录
NF: 当前记录个数
特殊字段 $1,$2,···,$NF供awk程序使用
内建变量:
FILENAME: 当前输入文件的名称
FNR: 当前输入文件的记录数
FS: 字段分割字符
NF: 当前记录的字段数
NR: 在工作中的记录数
OFS: 输出字段分隔符(默认:" ")
ORS: 输出记录分隔符(默认:"\n")
RS: 输入记录分隔符(仅用于gawk和mawk的正则表达式)
牛X的单行程序
1.单词计数程序
[jackson@localhost ~]$ cat test.txt
hello world hello
[jackson@localhost ~]$ awk '{C += length($0); W += NF } END {print NR, W, C}' test.txt
1 3 17 分别为记录数,单词数,字符数
awk有默认的初始化保证,C,W,都默认初始化为0
2.整数的因式分解
# 计算整数的因式分解
# 语法:
# awk -f factorize.awk
{
n = int($1) # 转换为整型
m = n = (n >= 2) ? n : 2 # 小于2的参数一律置为2
factors = "" # 初始化结果
for (k = 2; (m > 1 && k * k <= n);)
{
if (int(m % k) != 0)
{
k++;
continue;
}
m /= k;
factors = (factors == "") ? "" k : (factors "*" k)
}
if ((1 < m) && (m < n))
factors = factors "*" m
print n, (factors == "") ? "is prime" :("= " factors)
}