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(条件判断){}

例题

# 每隔五行打印一次--------

posted @ 2021-12-22 22:22  谢俊杰  阅读(48)  评论(0编辑  收藏  举报