linux三剑客之awk 文本分析工具


目录
  • linux三剑客之awk
    • awk的生命周期
    • awk中的预定变量
    • awk处理规则的流程
    • awk中的函数
    • awk中的定位
    • 流程控制

linux三剑客之awk

定义 :主要用来格式化文本。

语法格式 : awk [参数] [处理规则] [操作对象]

参数 : -F  : 指定文本分隔符(默认是以空格作为分隔符的)
	
	例 : 打印系统所有用户的解析器
		awk -F: '{print $NF}' /etc/passwd 
	

awk的生命周期

三剑客中: grep 、sed 、awk 都是读一个处理一行 ,直至处理完成

生命周期:
	1、接受一行作为输入
	2、把刚刚读入进来得到文本进行分解
	3、使用处理规则处理文本
	4、输入一行,赋值给$0,直至处理完成
	5、把处理完成之后的所有的数据交给END{}来处理
	

awk中的预定变量

$0  : 代表当前行
	例 : awk -F: '{print $0, "--"}' /etc/passwd  # 
	
$n  : 代表第n列
	例 :awk -F: '{print $1}' /etc/passwd  # 这就打印为第一列的内容	
	
NF  :记录(统计)当前行的字段数  (常与 $ 配合使用)
	例 : awk -F: '{print NF}' /etc/passwd  # 以 : 作为分割符 则打印每一行有多少列
	
$NF :$  :取变量里的值 NF相当于统计字段数  
	 $NF :就相当于取每一行的最后一个字段(最后一列)的内容

NR  :用来记录行号

FS  :指定文本分隔符 (默认为空格) # 相当于参数 -F 但是优先级大于参数 -F
	[root@localhost ~]# awk 'BEGIN{FS=":"}{print $1, $NF}' /etc/passwd
相当于:
	[root@localhost ~]# awk -F: '{print $1, $NF}' /etc/passwd
	
OFS :指定打印分隔符 (默认为空格)
	[root@localhost ~]# awk -F: 'BEGIN{OFS=" >> "}{print $1, $NF}' /etc/passwd

awk处理规则的流程

# 处理流程至少有一个 所以开始必须为BEGIN()

BEGIN{}   : 最开始处理
//	  : 正则
{}  	  : 循环
END{} 	  : 打印之前整体的处理

awk中的函数

print   : 打印
printf  : 格式化打印
%s      : 字符串
%d      : 数字
-       : 左对齐
+       : 右对齐
数字    :  至少占用多少个字符

例题:

[root@localhost ~]# awk -F: 'BEGIN{OFS=" | "}{printf "|%-15s|%-15s|\n", $NF,$1}' /etc/passwd

解析 : awk 命令
	   -F: 指定分隔符为 :
	   BEGIN{OFS= " | "} : BEGIN处理流程第一步:指定打印分隔符为 |
	   {printf "|%-15s|%-15s|\n", $NF,$1}    :printf 格式化打印
	   					 :"" 外边为单引号 内部则要用双引
	   					 :%-15s : 左对齐字符串至少占用15个字符 
	   					 :\n 换行符
	   					 :$NF 取每一行的最后一段(最后一列)
	   					 :$1  取每一行的第一段(第一列)
		/etc/passwd : 路径文件
		

awk中的定位

1、正则表达值:
	例题:[root@localhost ~]# awk -F: '/root/{print $0}' /etc/passwd
	解析:// 中间为正则表达式 则就是匹配正则为root的行

2、比较表达式
	
	>	: 大于
	<	: 小于
	>=	: 大于等于
	<=	: 大于等于
	~ 	: 正则匹配
	!~	: 正则匹配(取反)
	
案例:

1、要求打印属组ID大于属主ID的行
	[root@localhost ~]# awk -F: '$4>$3{print $0}' /etc/passwd
	解析: 属组ID在文本以: 分割在第4个字段 属主在第三个字段 所有比较这两个字段就可以
	
2、打印结尾包含bash
	[root@localhost ~]# awk -F: '$NF ~ /bash/{print $0}' /etc/passwd
	

3、逻辑运算符

&&	:	与
||	:	或
!	:	非
例题:
	
1、打印出属主属组都大于0的用户
	[root@localhost ~]# awk -F: '$4>0 && $3>0' /etc/passwd

2、打印出属主属组相加大于1000或者 属主属组相乘大于1000的用户
	[root@localhost ~]# awk -F: '$4+$3>1000 || $4*$3>1000' /etc/passwd
	
3、打印出属主属组相加不大于
	[root@localhost ~]# awk -F: '!($4+$3>1000 || $4*$3>1000)' /etc/passwd
4、算数表达式
	
	+       相加
	-	相减
	*	相乘
	/	相除
	%	取余
	
案例:

1、要求打印出偶数行
	[root@localhost ~]# awk -F: 'NR % 2 == 0{print $0}' /etc/passwd
	解析 : NR统计行 行除以2取余 余数为0则为偶数

2、要求打印出计数行
	[root@localhost ~]# awk -F: 'NR % 2 == 1{print $0}' /etc/passwd
5、条件表达式
	
	== 
	>
	<
	>=
	<=
	
# 其实比较表达式也相当于条件表达式

案例:
	
	要求打印某一行内容:
		[root@localhost ~]# awk -F: 'NR == 3{print $0}' /etc/passwd
		# 运用 == NR == 3 则打印第三行内容
		

6、范围表达式
	
前一段	,后一段 : 表示前一段至后一段的范围

案例:
	打印出开头为root 到 开头为ftp 的内容

流程控制

只存在循环{}之中

作用相当于python中的但格式不一样。

if 		: 判断
for		: 循环
while		: 循环

if :

	if(){}
	if(){}else if(){}
	if(){}else(){}

	[root@localhost ~]# awk -F: '{if($3>$4){print "大于"}else{print "小于或等于"}}' /etc/passwd
	
for :
	
	for(i="初始值";条件判断;游标){}

	[root@localhost ~]# awk -F: '{for(i=5;i>0;i--){print $0}}' /etc/passwd
	
	# 每一行循环打印5遍
	
while:
	
	while(条件判断){}
	
	[root@localhost ~]# awk -F: '{i=1;while(i<10){print $0, i++}}' /etc/passwd
	
	# 每一行循环打印10遍

案例:
	
1、每隔5行,打印一行横线
 [root@localhost ~]# awk -F: '{if(NR%5==0){print"---------------"}print $0}' /etc/passwd