shell脚本 awk工具

时间:2021-06-21 16:04:21

awk工具概述
awk编程语言/数据处理引擎
基于模式匹配检查输入文本,逐行处理并输出
通常在shell脚本中,或取指定的数据
单独用时,可对文本数据做统计

命令格式
格式一:awk [选项] '[条件]{编辑指令}' 文件
格式二:前置命令 | awk [选项] '[选项]{编辑指令}'

常用命令选项:
-F:指定分隔符,可省略(默认空格或tab位)
-f:调用awk脚本进行处理
-v:调用外部shell变量

实例:
[root@ceshiji ~]# awk '{print $1}' /etc/passwd
[root@ceshiji ~]# awk -F: '{print $1}' /etc/passwd

awk内置变量
有特殊含义,可直接使用
变量用途
FS保存或设置字段分隔符,例如 FS=":"
$n指定分隔得第n个字段,如$1,$3分别表示第1,第3列
$0一整行
NF记录当前处理行的字段列数
NR当前行号
FNR当前行在源文件中的行号
FILENAME当前处理的文件名
ENVIRON调用shell环境变量,格式:ENVIRON["变量名"]

实例:
[root@ceshiji ~]# awk '/Failed/{print $11}' /var/log/secure |uniq -c(统计本机被攻击次数)

awk过滤的时机:
(可单独使用,也可以同时一起使用)

所有行前处理:
ENVIRON{}
读入第一行文本之前执行
一般用来初始化操作

逐行处理:
{}
逐行读入文本执行相应的处理
是最常见的编辑指令块

所有行后处理:
END{}

处理完最后一行文本之后再执行
一般用来输出处理结果


实例:
[root@ceshiji ~]# awk 'BEGIN{a=34;print a+12}'(预处理不需要数据文件)
[root@ceshiji ~]# awk 'BEGIN{x=0}/\<bash>$/{x++}\END{print x}' /etc/passwd(统计bash用户个数)

处理条件概述
条件的表现形式
正则表达式
数值/字符串比较
逻辑比较
运算符

正则表达式
/正则表达式/
~匹配,!~不匹配
[root@ceshiji ~]# awk -F: '/^ro/{print}' /etc/passwd(列出以ro开头的用户记录)
[root@ceshiji ~]# awk -F: '$7!~/bash$/{print $1,$7}' /etc/passwd(列出第7个字段不以bash结尾的用户名登陆shell)

数值比较
==:等于
!=:不等
>:大于
>=:大于等于
<:小于
<=:小于等于
[root@ceshiji ~]# awk 'NR==2{print}'a.txt(输出第二行文本)
[root@ceshiji ~]# awk '$2="xx"{print}'a.txt(输出第二列不是xx的行)
[root@ceshiji ~]# awk 'NF>=2{print}'a.txt(输出包含2个及以上字段的行)

逻辑比较测试
&&:期望多个条件都成立
||:只要有一个条件成立即满足要求
[root@ceshiji ~]# awk -F: '$3>=0&&$3<2{print$1,$3}'/etc/passwd(列出uid小于2的用户信息)

运算符
+ - * / %
++ -- += -= *= /=
[root@ceshiji ~]# awk 'NR%2==1{print}'a.txt(输出奇书行文本)


综合实例:
根据/etc/passwd提取密码串
找到使用bash作登陆shell的本地用户
列出这些用户的shadow密码记录
按每行 用户名——》密码记录 保存结果
#!/bin/bash
user=`awk -F '/bash$/s/:.*//p' /etc/passwd`
for i in $user
do
awk -F: -v x=$i '$1==x{print $2}' /etc/shadow
echo "$ipass$pass"
done

——————————————————————————————————————————————————

awk流程控制

分支结构:
单分支
if(条件){编辑指令}
双分支
if(条件){编辑指令1}else{编辑指令2}
多分支
if(条件){编辑指令1}else if(条件){编辑指令2}else{编辑指令N}

awk和shell的区别:
shell:if[];then
命令
else
fi

awk:if(END){命令}
else{命令}


实例:
统计uid大于或等于500的用户个数
统计uid大于500的用户个数
[root@ceshiji ~]#
awk -F: 'BEGIN{i=0;j=0}{if($3<=500){i++}}else{j++}}END{print i,j}' /etc/passwd

循环结构
while循环:
while(条件){编辑指令}
do while循环:
do{编辑指令}while(条件)

示例:
统计/etc/passwd文件内root出现次数,利用-F[:/]表示分隔符为:或者/
[root@ceshiji ~]# awk -F"[:/]" '{i=1;while(i<=NF){if($i="root"){j++}i++}}' /etc/passwd

for循环
for(初值;条件;步长){编辑指令}
[root@ceshiji ~]# awk 'BEGIN{for(i=1;i<=5;i++){print i}}'


其他控制语句
常用的中断,退出等awk指令
关键字含义
break结束当前的循环体
continue中止本次循环,转入下一次循环
next跳过当前行,读入下一行文本开始处理
exit结束文本读入,转入END{}执行,如果没有END{}则直接退出awk处理操作

——————————————————————————————————————————————————————
awk数组
提取数组的值
提取一个值:变量[下标]

提取所有值:
x[i],x[j]..
for(i in 变量){print 变量[i]}
for(i in x)

数组的定义及使用
定义数组
格式:数组名 [下标]=元素值
调用数组
格式:数组名[下标]
遍历数组
用法:for(变量 in 数组名){print 数组名[变量]}
实例:为数组name赋值两个元素,值分别为jim,tom
[root@ceshiji ~]# awk 'BEGIN{name[0]="jim";name[1]="tom";print name[0],name[1]}'

awk数组的经典应用
去除文本的重复行
用法:awk '!a[$0]++' fileame
逐行分析,遇到重复行跳过
实例:列出/etc/passwd中的登陆shell种类
[root@ceshiji ~]# awk -F: '!a[$7]++{print $7}' /etc/passwd

sort工具
-n:按数字升序排列
-k:针对指定的字段进行排序
-r:反向排序

————————————————————————————————————————————————————————