三剑客之awk命令 一、简介

awk命名源自于它的三大作者名字的首字母,分别是Alfred Aho、Brian Kernighan、Peter Weinberger。(gawk是awk的GNU版本,它提供了Bell实验室和GNU的一些扩展)。

awk 是一种编程语言,用于在linux/unix下对文本和数据进行处理。数据可以来自标准输入、一个或多个文件,或其它命令的输出。它支持用户自定义函数和动态正则表达式等先进功能,是linux/unix
下的一个强大编程工具。它在命令行中使用,但更多是作为脚本来使用。

awk的处理文本和数据的方式是这样的,它逐行扫描文件,从第一行到最后一行,寻找匹配的特定
模式的行,并在这些行上进行你想要的操作。如果没有指定处理动作,则把匹配的行显示到标准输出(
屏幕),如果没有指定模式,则所有被操作所指定的行都被处理

awk 格式

-F  定义字段分隔符 ,默认是空格
#两种语法格式
awk [optinos]  'commands' filename
awk [optinos] -f awk-script-file  filename

# awk命令由三部分组成
GEGIN{} 	#读取所有行之前做的事情
{}			#读一行处理一行
END{}		#读完之后要做的事情
可以省略BEGIN{}END{},只进行{}处理,并且{}可以加匹配,成功后在处理

示例:
awk -F: '/root/{print $1,$3}' /etc/passwd
df -P |awk '$4 > 999999{print $0}'
#{print $0}可以省略,有默认输出
二、工作原理
1.awk会接收一行作为输入,并将这一行赋给awk的内部变量$0,每一行也可称为一个记录,行的边界是以换行符作为结束
2.读入的行,分隔符分解成若干字段,每个字段存储在编好的变量中,从$1开始,最多有100多个字段
3.使用print函数打印,OFS默认空格,如果打印$1,$3逗号分开,就会默认打印出来进行空格分开。可以自行设置OFS
三、记录与字段相关内部变量
$0		当前行的内容
NR		记录号,行号,处理完一条NR+1
NF		保存记录的字段数,如$1,$2
FS		输入字段分隔符,默认空格
OFS		输出字段分割符,默认空格
$NF		最后一列
四、格式化输出
%s 		字符类型
$d		数值类型
-		表示左对齐,默认是右对齐
printf默认不会再行尾自动换行,需要自行加\n

awk -F: '{printf "|%-15s|%-15s|%-15s|\n",$1,$2,$3}' /etc/passwd
五、模式pattern与动作action
1.正则表达式
awk -F: '/egon/{print $1,$3}' 
awk '$1 ~ /^root/'  /etc/passwd
awk '$7 !~ /bash$/'  /etc/passwd

2.比较表达式---条件为真,再执行
<		#小于
<=		#小于等于
>		#大于
>=		#大于等于
==		#等于
!=		#不等于
~		#匹配
!~		#不匹配

3.算数运算
+ - * / % ^

4.逻辑运算和复合运算
&&		#逻辑与
||		#逻辑或
!		逻辑非
# awk '!($2 < 100 && $3 < 20)' filename	

5.范围模式
NR > 3 && NR < 5  NR==3
awk '/root/,/egon/' /etc/passwd
awk '/root/,/jerry/{print NR,$1}' /etc/passwd
七、流程控制
条件判断:if  else if    else   == 
{if (表达式) {语句;语句;...}
awk -F: '{if ($3==0){i++} else if ($>499){k++}else {j++}} END{print "管理员个数:"i;print"普通用户个数:"k;print"系统用户:"j}' /etc/passwd

while 循环
awk -F: 'i=1;while(i<=10) {print $0;i++}' /etc/passwd

for循环
awk -F: '{for(i=1;i<=10;i++) print $0}' /etc/passwd

数组(索引或key对应值)
# awk -F: '{username[++i]=$1} END{print username[1]}' /etc/passwd

# awk -F: '{username[i++]=$1} END{print username[1]}' /etc/passwd 

# awk -F: '{username[i++]=$1} END{print username[0]}' /etc/passwd 

# awk -F: '{username[x++]=$1} END{for(i=0;i<NR;i++) print i,username[i]}' /etc/passwd
练习题
1. 取得网卡IP(除ipv6以外的所有IP)
2. 获得内存使用情况
3. 获得磁盘使用情况
4. 清空本机的ARP缓存
5. 打印出/etc/hosts文件的最后一个字段(按空格分隔)
6. 打印指定目录下的目录名
7.已知一个变量 msg="I am a teacher, my name is egon",打印字符长度小于3的单词