linux awk
目录
awk
awk参数-F,NF
awk 主要用于格式化文本
1. awk 语法
awk [参数] [处理规则] [操作对象]
2. 参数
-F : 指定文本分隔符 (默认以空格作为分隔符)
[root@localhost ~]# cat 2.txt
1 2
1 2 3
1 2 3 4
NF : 默认取每一行的最后一列
[root@localhost ~]# awk '{print $NF}' 2.txt
2
3
4
[root@localhost ~]# cat 2.txt
1 2
1 2 3
1 2 3 4
1 2 3 4 51 2
1 2 3
1 2 3 4
1 2 3 4 5
[root@localhost ~]# awk -F '1' '{print $NF}' 2.txt
2
2 3
2 3 4
2
2 3
2 3 4
2 3 4 5
# 如果参数-F有指定分隔符,那么默认分割每一行最后一个指定分隔符开始分隔
案例1:打印系统所有用户的解析器
[root@localhost ~]# awk -F: '{print $NF}' /etc/passwd
awk生命周期
grep,sed和awk都是读一行处理一行,一直到处理完成
1.接收一行作为输入
2.把刚读入得到的文本进行分解
3.使用处理规则处理文本
4.输入一行 赋值给$0 一直到处理完成
5.再把处理完成之后的所有数据交给END{}来再次处理
awk中的预定义变量
$ : 取变量里面的值
$0 : 代表当前行
[root@localhost ~]# awk '{print $0,"---"}' /etc/passwd (按照生命周期思考)
$n : 代表第n列
[root@localhost ~]# awk -F: '{print $1}' /etc/passwd(打印出由:分割的第一列)
# NF : 记录当前行的字段数()
[root@localhost ~]# awk '{print NF}' /etc/passwd
输出已(空格)为分割符后的数字
或指定分隔符(:)
[root@localhost ~]# awk -F: '{print $NF}' /etc/passwd
打印最后一列
# NR : 用于记录行号
[root@localhost ~]# awk '{print NR}' /etc/passwd
FS : 指定文本内容分割符
[root@localhost ~]# awk 'BEGIN{FS=':'{print &NF}}' /etc/passwd
FS的作用于-F相同, 但是FS的优先级大于-F
[root@localhost ~]# awk -F: 'BEGIN{FS="x"}{print $NF}' /etc/passwd
OFS : 指定打印分隔符(默认空格)
[root@localhost ~]# awk -F: 'BEGIN{OFS=" >>> "}{print $NF, $1}' /etc/passwd
(每行之间是由:相隔,先打印字段数,在打印第一列)
awk的处理规则执行流程
BEGIN{} :最开始执行
// : 正则
{} :循环 (处理文本)
END{} : 打印之前再同意处理一遍打印
# 执行顺序是从上而下
"一般定义变量在BEGIN{}中定义"
awk中的行数
print :打印
printf :格式化打印
%s : 字符串
%d : 数字
[root@localhost ~]# awk 'BEGIN{OFS=" | "}{printf "|%-15s|%s|\n", $1,$NF}' 1.txt
(指定分隔符为|,("|%-15s|%s|\n" $1,$NF)=(|$1|$NF|)-->(|15字节|)
- :左对齐
+ :右对齐
15 : 至少占用15字符
# 函数只能应用于{},END{}
awk中的定位
1.正则表达式
2.比较表达式
3.逻辑表达式
4.算式表达式
5.条件表达式
6.范围表达式
正则表达式
# 打印passwd中带root的行
[root@localhost ~]# awk 'BEGIN{FS=":"} /root/ {print $0 }' /etc/passwd
或
[root@localhost ~]# awk -F: '/root/{print $0}' /etc/passwd
# 打印passwd中以root开头的行
[root@localhost ~]# awk 'BEGIN{FS=":"} /^root/ {print $0 }' /etc/passwd
或
[root@localhost ~]# awk -F: '/^root/{print $0}' /etc/passwd
比较表达式
>
<
>=
<=
~ 正则匹配
!~ 正则匹配(取反)
# 要求答应passwd属组大于属主的ID的行
[root@localhost dev]# awk -F: '$4 > $3{print $0}' /etc/passwd
# 要求打印结尾包含bash的行
awk '$NF ~ /bash/ {print $0}' /etc/passwd
# 结尾不包含bash
[root@localhost ~]# awk -F: '$NF !~ /bash/{print $0}' /etc/passwd
逻辑表达式
&& : 逻辑(与)
|| : 逻辑(或)
!: 逻辑(非)
# 打印属组属主相加大于2000和相乘大于2000
[root@localhost ~]# awk -F: '$3 + $4 > 2000 && $3 * $4 > 2000{print $0}' /etc/passwd
# 打印属组属主相加大于2000或者相乘大于2000
[root@localhost ~]# awk -F: '$3 + $4 > 2000 || $3 * $4 > 2000{print $0}' /etc/passwd
# 取小于或等于2000的
[root@localhost ~]# awk -F: '!($3 + $4 > 2000){print $0}' /etc/passwd
算式表达式
+
-
*
/
% (取余,相处之后只返回余数)
比如: 5%2=4余1 (1是基数)
案例:要求属组 + 属主的ID 大于 2000
[root@localhost ~]# awk -F: '$3 + $4 > 2000{print $0}' /etc/passwd
案例:要求属组 * 属主的ID 大于 2000
[root@localhost ~]# awk -F: '$3 * $4 > 2000{print $0}' /etc/passwd
案例: 要求打印偶数行
[root@localhost ~]# awk -F: 'NR % 2 == 0{print $0}' /etc/passwd
案例:要求打印奇数行
[root@localhost ~]# awk -F: 'NR % 2 == 1{print $0}' /etc/passwd
条件表达式
==
>
<
>=
<=
# 要求打印第三行
[root@localhost ~]# awk -F: 'NR == 3{print $0}' /etc/passwd
范围表达式
范围表达式(从一个地方到一个地方)
[root@localhost ~]# awk '/^root/,/^ftp/{print $0}' /etc/passwd
流程控制
if
if
# 如果$3+$4>2000打印否则打印小于
[root@localhost dev]# awk -F: '{if($3 + $4 > 20){print $0}else{print "小于"}}' /etc/passwd
'单分支if(){}'
'双分支if(){}else{}'
'多分支if(){}else if(){}else{}'
for
for
# 每行打印十次
[root@localhost dev]# awk -F: '{for(i=10;i>0;i--){print $0}}' /etc/passwd
for(i="初始值";条件判断;游标){} # 游标--》每次处理
while
每行打印9次
[root@localhost dev]# awk -F: '{i=1; while(i<10){print $0, i++}}' /etc/passwd
while(条件判断){}
例题
# 每隔五行打印一次--------