三剑客之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的单词