文本格式化工具AWK
AWK:
概述:
grep,sed,awk 是 shell 编程中经常用到的文本处理工具(shell编程三剑客)。 awk 命令名称来源于它的三个开发者 Aho、 Weinberger 和 Kernighan 名字首字母的缩写,它是一种编程语言,主要用来处理结构化的数据和生成格式化的报告。awk可以在非交互的情况下完成相当复杂的文本处理操作。
awk 提供了极其强大的功能:它可以完成 grep 和 sed 所能完成的所有工作,同时,还可以进行样式装入、流程控制、数学运算符、进程控制语句甚至于使用内置的变量和函数。
格式:
l awk 选项 ‘模式或条件{编辑指令}’ 输入文件
l awk -f 脚本文件 输入文件
awk工作原理:
在 Linux 系统中/etc/passwd是一个非常典型的格式化文件,各字段(列)间使用“:”作为分隔符隔开, Linux 系统中的大部分日志文件也是格式化文件,从这些文件中提取相关信息是运维的日常工作内容之一。
AWK:
概述:
grep,sed,awk 是 shell 编程中经常用到的文本处理工具(shell编程三剑客)。 awk 命令名称来源于它的三个开发者 Aho、 Weinberger 和 Kernighan 名字首字母的缩写,它是一种编程语言,主要用来处理结构化的数据和生成格式化的报告。awk可以在非交互的情况下完成相当复杂的文本处理操作。
awk 提供了极其强大的功能:它可以完成 grep 和 sed 所能完成的所有工作,同时,还可以进行样式装入、流程控制、数学运算符、进程控制语句甚至于使用内置的变量和函数。
格式:
l awk 选项 ‘模式或条件{编辑指令}’ 输入文件
l awk -f 脚本文件 输入文件
awk工作原理:
在 Linux 系统中/etc/passwd是一个非常典型的格式化文件,各字段(列)间使用“:”作为分隔符隔开, Linux 系统中的大部分日志文件也是格式化文件,从这些文件中提取相关信息是运维的日常工作内容之一。
若需要查找出/etc/passwd 的用户名、用户 ID、组 ID等列,使用下面的 awk 命令就可完成:
awk 从输入文件或者标准输入中读入信息,与 sed 一样信息的读入也是逐行读取的。不同的是 awk 将文本文件中的一行视为一个记录,而将一行中的某一部分(列)作为记录中的一个字段(域)。为了操作这些不同的字段, awk 借用 shell 中类似于位置变量的方法,用$1, $2, $3…这样的顺序地表示行(记录)中的不同字段。另外awk 用$0 表示整个行(记录)。不同的字段之间是用称作分隔符的字符分隔开的。awk默认的分隔符是空格和制表符。 awk 允许在命令行中用[-F 分隔符]的形式来指定分隔符。
在上述示例中, awk 命令对/etc/passwd 的处理过程如图所示。
编辑指令的分隔:
l 编辑指令若包含多条命令语句,则以分号隔开。
[root@localhost ~]# free | awk '/^Mem:/{num=int($3/$2*100); print "内存使用百分比:"num"%"}'
内存使用百分比:34%
l 如果有多条编辑指令,则使用以分号或者空格分隔的多个{ }区域。
命令区块构成:
l BEGIN { 编辑指令 //开始处理第一行文本之前的操作
l { 编辑指令 //针对每一行文本的处理操作
l END { 编辑指令 //处理完最后一行文本之后的操作
awk的执行流程:
1. 首先执行 BEGIN { } 区块中的初始化操作;
2. 然后从指定的数据文件中循环读取一个数据行(自动更新NF、NR、$0、$1…… 等内建变量的值),并执行'模式或条件{ 编辑指令 }';
3. 最后执行 END { } 区块中的后续处理操作
awk在使用的过程中,可以使用逻辑操作符&&,表示“逻辑与”,||表示“逻辑或”,!表示“逻辑非”;还可以进行简单的数学运算,如+、-、*、/、%、^分别表示加、减、乘、除、取余、乘方。
Awk练习文本:
此文本文件有7个域,即
(1)名字
(2)升段日期
(3)学生序号
(4)腰带级别
(5)年龄
(6)目前比赛积分
(7)比赛最高分
因为域间使用空格作为域分隔符,故不必用-F选项划分域
从windows中导入时,如果文本中有空行或特殊字符,先处理好,以方便后续操作
练习案例:
打印出全文内容(等同于cat):
输出文件第一列和第四列:默认用逗号分隔,也可以指定分隔的字符或制表符号[root@localhost]# awk '{print $1,$4}' grade.txt
\t:代表tab键,水平制表位
格式化输出
在输出到文件的同时输出到屏幕
awk条件操作符:
操作符 | 描述 |
< | 小于 |
> | 大于 |
<= | 小于等于 |
== | 等于 |
!= | 不等于 |
>= | 大于等于 |
~ | 匹配正则表达式 |
!~ | 不匹配正则表达式 |
判断整行是否匹配Brown,匹配则输出整行,要匹配的内容(查找的内容)用//指定或用比较操作符
[root@localhost ~]# awk '$0~/Brown/{print $0}' grade.txt
J.Troll 07/99 4842 Brown-3 12 26 26
L.Tansley 05/99 4712 Brown-2 12 30 28
如果是整行匹配,$0~可以省略,当有编辑命令时,如果输出内容是整行,{print $0}也可以省略,默认即为输出整行
[root@localhost ~]# awk '/Brown/' grade.txt
J.Troll 07/99 4842 Brown-3 12 26 26
L.Tansley 05/99 4712 Brown-2 12 30 28
判断第三列是否等于48,匹配则输出整行(更加严格)
判断整行是否不匹配Brown,不匹配则输出整行
判断第四列是否等于Brown-2,不等于则输出整行
过滤文件中的Green或green
判断第一列第四个字母是a的
判断整行匹配Yellow或者Brown
过滤P开头的行
输出密码为空的用户行
awk的内置变量:
l FS: 指定每行文本的字段分隔符,缺省为空格或制表位
l OFS: 指定输出字段的分隔符,默认为空格
l NF: 当前处理的行的字段个数(列数)
l NR: 当前处理的行的序数(行数)
l FILENAME: AWK浏览的文件名
l $0: 当前处理的行的整行内容
l $n: 当前处理的第n个字段(第n列)
统计行数和列数
root@localhost ~]# awk 'END {print NR}' grade.txt
5
[root@localhost ~]# awk '{print NR}' grade.txt
1
2
3
4
5
NF:内置变量NF代表的是每行的总列数(字段数),$NF代表最后一字段的内容
[root@localhost ~]# awk '{print NF}' grade.txt
7
7
7
7
7
[root@localhost ~]# awk 'END {print NF}' grade.txt
7
FS:内置变量FS代表分隔文件的分隔符,在命令选项中可以用-F指定,默认为空格
OFS:内置变量OFS代表输出时各个字段间的分隔符,默认为空格
head -5 /etc/passwd | awk -F: '{print $1,$7}'
输出第1行~第3行的内容:
输出第1行和第3行的内容:
输出所有奇数行:
输出所有偶数行:
统计当前所有系统用户的用户名、UID、GID、登录的shell,制成Windows系统中的EXCEL表格:(工作中常用到)
NF代替(最后一列)
当前内存使用率超过85%时报警(取整数部分):
root@localhost ~]# vim mem.sh
#!/bin/bash
total=$(free -m | awk 'NR==2 {print $2}')
use=$(free -m | awk 'NR==2 {print $3}')
used=$(expr $use \* 100 / $total)
#为了测试效果将比较值设置为10%
if [ $used -gt 10 ]
then
echo "内存已达到${used}%"
fi
[root@localhost ~]# bash mem.sh
内存已达到20%
awk中引用shell变量
用单引号引用shell变量,值不能包含空格
awk条件判断语句
awk内置的条件语句是从C语言中借鉴过来的,可进行控制程序的流程。
单分支格式:
‘{if (表达式){
命令1;命令2; ...
}
}’
条件语句也是作为命令的一部分需要放在{}内,如果作为查找条件需要放在{}外
判断第四列是否匹配Brown,匹配则输出整行,匹配后如果只有一条命令{}可以省略,但命令不可以省略