1.说明
本文参考摘录自《Linux与Unix shell编程指南》
2.主要内容
如果要格式化报文或从一个大的文本文件中抽取数据包,那么awk可以完成这些任务。它在文本浏览和数据的熟练使用上性能优异。awk语言的最基本功能是在文件或字符串中基于指定规则浏览和抽取信息。awk抽取信息后,才能进行其他文本操作。完整的awk脚本通常用来格式化文本文件中的信息。
调用awk方式:
awk [-F field-separator] 'commmands' input-file(s) //命令行方式
(1)域分隔符和域
域分隔符:
[-F域分隔符]是可选的,因为awk使用空格作为缺省的域分隔符,因此如果要浏览域间有空格的文本,不必指定这个选项,但如果要浏览诸如passwd文件,此文件各域以冒
号作为分隔符,则必须指明-F选项。
如果设置了-F选项,则awk每次读一行(记录),并使用指定的分隔符分隔指定域;但如果未设置-F选项,awk假定空格为域分隔符,并保持这个设置直到发现一新行。当新行出现时,awk命令获悉已读完整条记录,划分这一行作为一条记录。接着awk再次启动下一行读进程然后在下一个记录启动读命令,这个读进程将持续到文件尾或文件不再存在。
域:
awk执行时,其浏览域标记为$1,$2 ...$n。这种方法称为域标识。使用这些域标识将更容易对域进行进一步处理。使用$1 ,$3表示参照第1和第3域,注意这里用逗号做域分隔(缺省的域分隔符为)。如果希望打印一个有5个域的记录的所有域,不必指明 $1,$2,$3 ,$4 ,$5,可使用$0,意即所有域。
(2)模式和动作
任何awk语句都由模式和动作组成。在一个awk脚本中可能有许多语句。模式部分决定动作语句何时触发及触发事件。处理即对数据进行的操作。如果省略模式部分,动作将时刻保持执行状态。
模式可以是任何条件语句或复合语句或正则表达式。模式包括两个特殊字段BEGIN和END。使用BEGIN语句设置计数和打印头。BEGIN语句使用在任何文本浏览动作之前,之后文本浏览动作依据输入文件开始执行。 END语句用来在awk完成文本浏览动作后打印输出文本总数和结尾状态标志。如果不特别指明模式,awk总是匹配或打印行数。
实际动作在大括号{ }内指明。动作大多数用来打印,但是还有些更长的代码诸如 if和循环(looping)语句及循环退出结构。如果不指明采取动作,awk将打印出所有浏览出来的记录。
(3)具体应用
//共有7个域,域间使用空格作为域分隔符,故不必用-F选项划分域
例子1:AWK打印操作
1.打印所有记录
$awk '{print $0}' grade.txt
//awk读每一条记录。因为没有模式部分,只有动作部分 {print $0}(打印所有记录),这个动作必须用花括号括起来。上述命令打印整个文件。
2.打印单独记录
$awk '{print $1,$4}' grade.txt
//只打印field -1和field -4,因此可以使用$1和$4,但不要忘了加逗号以分隔域。
3.打印消息头,信息尾
$awk 'BEGIN {print"Name\n-------"} {print $1} END {"end-of-report"}' grade.txt
例子2:AWK条件操作符与正则表达式(正则表达式用斜线括起来)
为使一域号匹配正则表达式,使用符号‘~’后紧跟正则表达式,也可以用if语句。awk中if后面的条件用()括起来
1.打印field-4包含Brown的记录
$awk '{if($4~/Brown/) print$0}' grade.txt
//"Brown"部分可换其他正则表达式
2. 打印field-4不包含Brown的记录
$ awk '{if($4!~/Brown/) print$0}' grade.txt
例3:AWK内置变量
NR 记录个数
NF 变量显示每一条读记录中有多少个域
FILENAME输入文件名
$awk '{print NR,NF,$0} END{printFILENAME}' grade.txt
(4)小结
awk是shell编程的一个重要工具,shell命令或编程中,awk具有强大的文本处理能力。上诉例子只列举了awk的简单基本功能,进一步学习请查看awk相关书籍。
3.实用demo
获取网络相关信息
IpAddr=`/sbin/ifconfig enp0s8 | grep "inet addr" | awk '{print $2}' | awk -F: '{print $2}'`
GateWay=`/bin/ip route|grep default|awk '{ print $3 }'`
IpMask=`/sbin/ifconfig enp0s8 | grep "Mask" | awk '{print $4}' | awk -F: '{print $2}'`
IpBcast=`/sbin/ifconfig enp0s8 | grep "Bcast" | awk '{print $3}' | awk -F: '{print $2}'`
Mac=`/sbin/ifconfig enp0s8 | grep "HWaddr" | awk '{print $5}'`
echo "the IpAddr is $IpAddr"
echo "the GateWay is $GateWay"
echo "the IpMask is $IpMask"
echo "the IpBcast is $IpBcast"
echo "the Mac is $Mac"