Linux四剑客之awk

awk,可以说是一门语言了,单行脚本;
取行;
取列;
混合取行与列;
判断与循环;
数组;

格式:类似sed
awk 选项 '条件{动作}' 文件
条件:找谁;
动作:干啥
取出/etc/passwd第1列第3列和最后一列,注$0是代表整行
awk -F: 'NR==1{print $1,$3,$NF}' /etc/passwd | colunm -t // column -t,对齐每一列

awk执行流程:
和sed类似,一行一行的读取内容,然后找谁,干啥,符合条件,执行操作,不符合,下一行;
awk没有默认输出,默认只输出符合条件的动作条件;
awk和sed会一直执行到文件的最后一行,结束;
awk比sed复杂的地方在于,读文件之前和读文件完毕之后,的相关操作;
读文件之前,先处理选项,或者BEGIN{}里的内容,比如,-F:,先处理分隔符;
读文件之后,处理END{}里的内容,BEGIN和END现在都很少用了;

取行
案例1:取出/etc/passwd的第1行
awk 'NR==1{print $0}' /etc/passwd //NR,Number Record,记录号,行号,仅取行,还可以简写
awk 'NR==1' /etc/passwd

案例2:取出第2行到第5行的内容
awk 'NR>=2 && NR<=5' /etc/passwd //&&表示并且,||表示或者,!=表示不等于;

案例3:过滤出/etc/passwd中包含root或noboey
awk '/root|nobody/' /etc/passwd

案例4:取出包含root的行到包含nobody的行
awk '/root/,/nobody/' /etc/passwd


小结:
awk + NR 取出指定的行,指定范围的行;
awk + // 过滤
awk + 其他变量功能用于精确过滤。(需要配合取列功能使用)
awk -F: '$3>=1000' /etc/passwd //取第3列大于1000的行,也就是UID大于1000

取列
案例:使用awk取出ls -l的大小列和最后一列
ls -lh /etc/hosts | awk '{$5,$NF}'
grep -i failed secure.log | head | awk '{print $(NF-3)}'

awk默认以空白字符分隔,可以加选项-F指定分隔符,如-F:,-F':',-F[: ],-F[/: ]+,都可以

对齐:column -t
awk -F: '{print $1,$3,$NF}' /etc/passwd | column -t

案例:指定复杂分隔符,同时也是取行取列
[root@web01 ~]# ip a s eth0 | awk -F'[ /]+' 'NR==3{print $3}'
stat /etc/hosts | awk -F'[/(]' 'NR==4{print $2}'


对列的判断,取出/etc/passwd中UID大于100的行,取出这行中第1列,第3列和最后一列;
awk -F: '$3>100{print $1,$3,$NF}' /etc/passwd

free | awk 'NR==3{print $3}'
free | awk '/Swap/{print $3}'
free | awk '/Swap/ && $3>=0 {print "系统异常占用Swap"}'

案例:过滤出/etc/passwd第4列的数字是以0或1开头的行,输出第1列,第3列
之前^或$表示某一行的开头或结尾
在awk中因为awk可以取列,通过列可以过滤这一列包含xxx,或者以x开头以x结尾;
awk -F: '$4 ~ /^[01]/' /etc/passwd //~,表示包含的意思,这里表示第4列包含以0或1开头的意思,!~,表示不包含;

awk统计与计算
1)统计次数
仅仅需要统计一下出现了多少次或者出现了多少个,还可以用wc -l
awk '{i=i+1;print i}' /etc/passwd //如果第一次执行i,为空(0)
awk '{i=i+1} END{print i}' /etc/passwd
2)计算总和
seq 10 > num.txt
# awk '{i=i+$1}END{print i}' num.txt

posted @ 2022-12-20 14:25  mclind  阅读(61)  评论(0编辑  收藏  举报