1、awk 简介
awk其名称来自于它的创始人 Alfred Aho 、Peter Weinberger 和 Brian Kernighan 姓氏的首个字母。实际上 AWK 的确拥有自己的语言: AWK 程序设计语言 , 三位创建者已将它正式定义为“样式扫描和处理语言”。它允许您创建简短的程序,这些程序读取输入文件、为数据排序、处理数据、对输入执行计算以及生成报表,还有无数其他的功能。
awk 是一种很棒的语言,它适合文本处理和报表生成,其语法较为常见,借鉴了某些语言的一些精华,如 C 语言等。在 linux 系统日常处理工作中,发挥很重要的作用,掌握了 awk将会使你的工作变的高大上。 awk 是三剑客的老大,利剑出鞘,必会不同凡响。
2、awk 语法
awk '{pattern + action}' {filenames}
尽管操作可能会很复杂,但语法总是这样,其中 pattern 表示 AWK 在数据中查找的内容,而 action 是在找到匹配内容时所执行的一系列命令。花括号({})不需要在程序中始终出现,但它们用于根据特定的模式对一系列指令进行分组。 pattern就是要表示的正则表达式,用斜杠括起来。
awk语言的最基本功能是在文件或者字符串中基于指定规则浏览和抽取信息,awk抽取信息后,才能进行其他文本操作。完整的awk脚本通常用来格式化文本文件中的信息。
通常,awk是以文件的一行为处理单位的。awk每接收文件的一行,然后执行相应的命令,来处理文本。
3、awk 原理
通过一个简短的命令,我们来了解其工作原理
[root@shell ~]#
[root@shell ~]# awk '{print $0}' /etc/passwd
你将会见到/etc/passwd 文件的内容出现在眼前。现在,解释 awk 做了些什么。调用 awk时,我们指定/etc/passwd 作为输入文件。执行 awk 时,它依次对/etc/passwd 中的每一行执行 print 命令。
所有输出都发送到 stdout,所得到的结果与执行 cat /etc/passwd 完全相同。
现在,解释{ print }代码块。在 awk 中,花括号用于将几块代码组合到一起,这一点类似于 C 语言。在代码块中只有一条 print 命令。在 awk 中,如果只出现 print 命令,那么将打印当前行的全部内容。
[root@shell ~]#
[root@shell ~]# awk -F":" '{ print $1 }' /etc/passwd
[root@shell ~]# awk -F":" '{ print $1 $3 }' /etc/passwd
[root@shell ~]# awk -F":" '{ print $1 " " $3 }' /etc/passwd
-F参数:指定分隔符,可指定一个或多个
print 后面做字符串的拼接
下面通过几实例来了解下awk的工作原理:
实例一:只查看test.txt文件(10行)内第2到第3行的内容(企业面试)
[root@shell ~]#
[root@shell ~]# touch test.txt
[root@shell ~]# vi test.txt
[root@shell ~]# cat test.txt
[root@shell ~]#
[root@shell ~]# awk '{if(NR>=2 && NR<=3) print $1}' test.txt
实例二:已知test.txt文件内容为 I am Poe,my qq is 33794712
[root@shell ~]# cat test.txt
I am Poe,my qq is 33794712
[root@shell ~]#
请从该文件中过滤出'Poe'字符串与33794712,最后输出的结果为:Poe 33794712
[root@shell ~]#
[root@shell ~]# awk -F '[ ,]+' '{print $3" "$7}' test.txt
BEGIN 和 END 模块
通常,对于每个输入行, awk 都会执行每个脚本代码块一次。然而,在许多编程情况中,可能需要在 awk 开始处理输入文件中的文本之前执行初始化代码。对于这种情况, awk 允许您定义一个 BEGIN 块。
因为 awk 在开始处理输入文件之前会执行 BEGIN 块,因此它是初始化 FS(字段分隔符)变量、打印页眉或初始化其它在程序中以后会引用的全局变量的极佳位置。
awk 还提供了另一个特殊块,叫作 END 块。 awk 在处理了输入文件中的所有行之后执行这个块。通常, END 块用于执行最终计算或打印应该出现在输出流结尾的摘要信息。
实例一:统计/etc/passwd的账户人数
[root@shell ~]#
[root@shell ~]# awk '{count++;print $0;} END{print "user count is ",count}' /etc/passwd
实例二:统计某个文件夹下的文件占用的字节数
统计/usr目录下文件占用的字节数
[root@shell ~]#
[root@shell ~]# cd /usr/
[root@shell usr]# ll |awk 'BEGIN {size=0;} {size=size+$5;} END{print "[end]size is ",size}'
如果以M为单位显示:
[root@shell usr]# ll |awk 'BEGIN{size=0;} {size=size+$5;} END{print "[end]size is ",size/1024/1024,"M"}'
awk 运算符
awk 赋值运算符:a+5;等价于: a=a+5;其他同类
[root@shell ~]#
[root@shell ~]# awk 'BEGIN{a=5;a+=5;print a}' #a+=5 等同于 a=a+5
[root@shell ~]# awk 'BEGIN{a=5;a=a+5;print a}'
10
[root@shell ~]#
awk逻辑运算符:
[root@shell ~]#
[root@shell ~]# awk 'BEGIN{a=1;b=2;print (a>2&&b>1,a=1||b>1)}'
0 1
[root@shell ~]#
awk正则运算符:
[root@shell ~]# awk 'BEGIN{a="100testaa";if(a~/100/) {print "ok"}}'
ok
[root@shell ~]#
[root@shell ~]# echo|awk 'BEGIN{a="100testaaa"}a~/test/{print "ok"}'
ok
[root@shell ~]#
关系运算符:
如: > < 可以作为字符串比较,也可以用作数值比较,关键看操作数如果是字符串就会转换为字符串比较。两个都为数字 才转为数值比较。字符串比较:按照ascii码顺序比较。
[root@shell ~]#
[root@shell ~]# awk 'BEGIN{a="11";if(a>=9){print "ok"}}'
[root@shell ~]#
[root@shell ~]# awk 'BEGIN{a=11;if(a>=9){print "ok"}}'
ok
[root@shell ~]#
awk 算术运算符:
说明,所有用作算术运算符进行操作,操作数自动转为数值,所有非数值都变为0
[root@shell ~]# awk 'BEGIN{a="b";print a++,++a}'
0 2
[root@shell ~]#
[root@shell ~]# awk 'BEGIN{a="20b4";print a++,++a}'
20 22
[root@shell ~]#
这里的a++ , ++a与javascript语言一样:a++是先赋值加++;++a是先++再赋值
三目运算符 ?:
[root@shell ~]#
[root@shell ~]# awk 'BEGIN{a="b";print a=="b"?"ok":"err"}'
ok
[root@shell ~]#
[root@shell ~]# awk 'BEGIN{a="b";print a=="c"?"ok":"err"}'
err
[root@shell ~]#
常用 awk 内置变量
awk 正则
正则应用
规则表达式
awk '/REG/{action} ' file,/REG/为正则表达式,可以将$0 中,满足条件的记录送入到:action 进行处理
[root@shell ~]#
[root@shell ~]# awk '/root/{print $0}' /etc/passwd #匹配所有包含root的行
[root@shell ~]#
[root@shell ~]# awk -F: '$5~/root/{print $0}' /etc/passwd #以顿号作为分隔符,匹配第5个字段是root的行
布尔表达式
awk '布尔表达式{action}' file 仅当对前面的布尔表达式求值为真时, awk 才执行代码块。
[root@shell ~]#
[root@shell ~]# awk -F: '$1=="root"{print $0}' /etc/passwd
[root@shell ~]# awk -F: '($1=="root")&&($5=="root") {print $0}' /etc/passwd
awk 的 if、循环和数组
条件语句
awk 提供了非常好的类似于 C 语言的 if 语句。