第十九章 awk
19.1 awk基础
本博文目录索引
[TOC]
一、初识awk
(一)什么是awk?
awk,全称:Aho Weinberger Kernighan
是一个报告生成器,用于格式化文本输出
(二)awk能做什么?
1、主要功能:格式化显示文档、或者打印报表
2、将给定的文本内容按照工程师想要的格式输出显示、或者打印成报表格式
3、日常用途:处理各种文档(比如日志信息),从中分析挖掘出工程师关心的必要数据,并且打印成报表
(三)CentOS7系统中的awk
1、gawk
在CentOS7(或者CentOS6)系统中,使用GNU项目组开发的gawk来实现awk的功能
Gawk is the GNU Project‘s implementation of the AWK programming language.
2、awk是一个软链接,指向gawk
[[email protected] ~]# ll /usr/bin/awk
软链接:/usr/bin/awk
真身:/usr/bin/gawk
STDOUT:
lrwxrwxrwx. 1 root 4 Mar 28 01:54 /usr/bin/awk -> gawk
(四)awk的基本语法
1、第一种语法格式
awk [options] ‘program‘ var=VALUE /PATH/TO/SOMEFILE...
(1)options:选项
(2)program:程序,使用awk语言,用单引号 ‘‘ 引起来
相对比较复杂,需要根据生产需求的逻辑关系编写awk程序代码,从而实现特定功能
2、第二种语法格式
awk [options] -f programFile var=VALUE /PATH/TO/SOMEFILE...
(1)-f programFile:将逻辑复杂的awk程序代码放在programFile程序文件中,用 -f 调用awk程序文件
3、第三种语法格式
awk [options] ‘BEGIN{action;...}pattern{action;...}END{action;...}‘ /PATH/TO/SOMEFILE...
(五)awk处理机制
1、逐行处理
(1)会在内存中开辟一块awk处理文本的内存空间
(2)每一次读入文件中的一行文本到内存空间进行处理
(4)自带循环:处理完第一行并输出,然后再读入第二行,以此类推
2、切割字段
(1)可以根据指定的分隔符,把读入的一行文本切割成若干的字段
(2)每个字段都有对应的变量来表示
变量 | 含义 |
---|---|
$0 | 读入的整行 |
$1 | 第一个字段 |
$n | 第n个字段 |
(3)默认的字段分隔符是 空白符 (空格、tab键)
(4)而且个数不限,多个连续的空白符被识别为一个空白符
(六)awk中的行与列
1、记录
(1)在awk中,把读入的一行称为“记录”,英文:record
(2)类似于Excel表的一行
(3)在awk中,一般需要手动指定“记录分隔符”,用来区分每一行
(4)默认使用 \n (回车换行符) 作为记录分隔符
2、字段
(1)在awk中,把切割后的每一列称为“字段”,英文:field
(2)类似于Excel表的每一列
(3)在awk中,一般需要手动指定“字段分隔符”,用来将读入的一行文本切割成若干的字段
(4)默认使用 空白符 (空格、tab键) 作为记录分隔符
3、小结
通用概念 | awk概念 | 默认分隔符 | 解释 |
---|---|---|---|
行 | 记录 | \n | 回车换行符 |
列 | 字段 | 空白符 | 空格、tab键 |
二、awk工作原理
(一)典型的语法格式
awk [options] ‘BEGIN{action;...}pattern{action;...}END{action;...}‘ /PATH/TO/SOMEFILE...
(二)执行流程
- 第一步:执行 BEGIN{action;...} 语句块,与文件无关
- 第二步:从文件或者STDIN中读取一行,然后执行 pattern{action;...} 语句块,它逐行扫描文本内容,从第一行到最后一行重复这个过程,直到文本内容全部被读取完毕
- 第三步:当读至输入流末尾时,执行 END{action;...} 语句块
(三)语句块使用场景
1、BEGIN语句块
BEGIN语句块在awk开始从输入流中读取行之前被执行,这是一个可选的语句块,比如:变量初始化、打印输出表格的表头等语句通常可以写在BEGIN语句块中
2、END语句块
END语句块在awk从输入流中读取完所有的行之后即被执行,它也是一个可选语句块,比如:打印所有行的分析结果这类信息汇总都是在END语句块中完成
3、pattern语句块
pattern语句块中的通用命令是最重要的部分,也是可选的。如果没有提供pattern语句 块,则默认执行{ print },即打印每一个读取到的行,awk读取的每一行都会执行该语句块
(四)program
1、program的组合
program:pettern{action statements;...}
2、pattern
(1)是action动作语句的触发条件
(2)仅当满足pattern模式条件时,才会执行action动作语句
(3)类似于grep的“条件过滤”
(4)可以省略:没有定义过滤规则,所有行都满足要求
3、action
(1)是动作语句
(2)可以省略:省略时默认执行 print $0
操作
(五)用法举例
1、省略pattern:默认匹配所有行,执行action语句
[[email protected]]# awk ‘{print "Hello AWK!"}‘ /etc/fstab
读取 /etc/fstab 文本的所有行,并在每一行的位置打印 Hello AWK!
STDOUT:
若干行 Hello AWK!
Hello AWK!
[此处省略更多信息]
2、BEGIN语句:不处理文件,直接执行action语句
[[email protected] ~]# awk ‘BEGIN{print "Hello AWK!"}‘
不处理任何文件,直接打印一行 Hello AWK!
STDOUT:
Hello AWK!
3、默认的字段分隔符
[[email protected] ~]# df | awk ‘{print $1,$5}‘
以默认的字段分隔符(空白符)将每一行文本切割若干字段,取出第一和第五个字段
STDOUT:
设备文件 空间利用率
/dev/sda1 11%
[此处省略更多信息]
4、 -F: 指定的字段分隔符
[[email protected] ~]# awk -F: ‘{print $1":"$3}‘ /etc/passwd
指定 : 作为字段分隔符,将每一行文本切割成若干字段,取出第一和第三个字段
STDOUT:
用户名 UUID
root 0
[此处省略更多信息]
冒号 : 需要用双引号 "" 引起来,当作一个普通字符串
5、借助管道:处理其他命令的标准输出
[[email protected] ~]# tail -3 /etc/fstab | awk ‘{print $2,$4}‘
将 tail 命令的标准输出作为 awk 的标准输入,默认以 空白符 为字段分隔符,将每一行文本切割成若干字段,取出第二和第四个字段
STDOUT:
挂载点 挂载选项
/boot defaults
[此处省略更多信息]
三、内置变量
(一)FS:字段分隔符(field separator)
(1)以指定的字段分隔符,将一行文本切割成若干字段
(2)省略不写时,默认以 空白符 作为字符分隔符处理一行文本
[[email protected] ~]# awk -v FS=: ‘{print $1FS$3}‘ /etc/passwd
注意:
FS 作为变量使用时,不需要加 $ 符号!!!
STDOUT:
用户名 : UUID
root:0
[此处省略更多信息]
(二)OFS:输出的字段分隔符(output field separator)
(1)以指定的字段分隔符,将输出的一行文本切割成若干字段
(2)省略不写时,默认以 空白符 作为字段分隔符处理输出的一行文本
(3)用来对输出信息进行格式化处理
[[email protected] ~]# tail -3 /etc/fstab | awk -v OFS=: ‘{print $2,$3,$4}‘
注意:
指定 OFS 之后,分隔符 , 会识别成指定的 OFS ,而不会是默认的 空白符 了!
STDOUT:
挂载点 : 文件系统类型 : 挂载选项
/boot:xfs:defaults
/data:xfs:defaults
swap:swap:defaults
(三)RS:记录分隔符(record separator)
(1)以指定的记录分隔符,将输入流切割成多行记录
(2)省略不写时,默认以 \n 作为记录分隔符处理输入流
[[email protected] ~]# cat > f1
[[email protected] ~]> a b:c
[[email protected] ~]> d:f gg
[[email protected] ~]# awk -v RS=: ‘{print $0}‘ f1
注意:
FS 指定 : 作为记录分隔符,替换默认的 \n ,将输入流切割成若干的行
STDOUT:
a b
c
d
f gg
(四)ORS:输出的记录分隔符(output record separator)
(1)以指定的记录分隔符,将输出流切割成多行记录
(2)省略不写时,默认以 \n 作为记录分隔符处理输出流
(3)用来对输出信息进行格式化处理
[[email protected] ~]# cat > f1
[[email protected] ~]> a b:c
[[email protected] ~]> d:f gg
[[email protected] ~]# awk -v ORS="---" ‘{print $0}‘ f1
注意!
$0 表示将整行输出
STDOUT:
将回车换行符替换为 ---
a b;c---d;f gg---
(五)NF:字段数量(number of field)
(1)NF 表示一行文本中有多少个字段(需要指定字段分隔符)
[[email protected] ~]# awk -v FS=: ‘{print NF,$NF,$(NF-1)}‘ /etc/passwd
注意!
$NF 表示最后一个字段的值
$(NF-1) 表示倒数第二个字段的值
STDOUT:
字段数量为7 第7个字段的值 第6个字段的值
7 /bin/bash /root
[此处省略更多信息]
(六)NR:记录数量(number of record)
(1)NR 表示当前行在输入流中处于第几行
(2)默认会将多个文本合并为一个输入流(需要指定记录分隔符)
[[email protected] ~]# awk -v FS=: ‘{print NR,$1}‘ /etc/passwd
注意!
多个文件会被合并到同一个输入流中去!
STDOUT:
当前行的编号 用户名
1 root
2 bin
[此处省略更多信息]
(七)FNR:按文件计算“记录数量”(file (1)FNR 表示当前行在不同输入流中处于第几行
(2)遇到多个文本会当做多个不同的输入流来对待(需要指定记录分隔符)
[[email protected] ~]# awk -v FS=: ‘{print FNR,$1}‘ /etc/passwd /etc/shadow
STDOUT:
在当前文件中的当前行的编号 用户名
1 root
2 bin
[此处省略更多信息]
1 root
2 bin
[此处省略更多信息]
(八)FILENAME:文件名
[[email protected] ~]# awk -v FS=: ‘{print FILENAME}‘ /etc/passwd
STDOUT:
若干行 文件名
/etc/passwd
[此处省略更多信息]
(九)ARGC:参数个数(arguments account)
(1)统计命令的参数个数
[[email protected] ~]# awk ‘{print ARGC}‘ /etc/passwd
STDOUT:
当前命令的参数个数
2
(十)ARGV:参数列表数组(arguments variable)
(1)把参数列表写入ARGV数组
(2)数组下标的范围:[0,命令的参数个数]
[[email protected] ~]# awk ‘{print ARGV[0],ARGV[1]}‘ /etc/passwd
STDOUT:
第一个参数 第二个参数
awk /etc/passwd
四、自定义变量
原文地址:https://www.cnblogs.com/GymUManAlvin/p/9043421.html