[ 知识是人生的灯塔,只有不断学习,才能照亮前行的道路 ]
0x00 前言简述
描述:前面作者已经介绍了文本处理三剑客中的 grep 与 sed 文本处理工具,今天将介绍其最后一个且非常强大的 awk 文本处理输出工具,它可以非常方便我们读取文件内容或者将命令执行内容,根据脚本进行自定义格式化美化输出。
Linux中的awk工具以其强大的文本处理能力而闻名,它是一种专门用于模式扫描和处理的编程语言。本章节将深入探讨awk的语法结构,并提供一份简明易懂的学习指南。我们将覆盖格式输出、变量操作、算术运算、模式匹配、流程控制、数组应用、函数定义以及脚本编写等核心概念,旨在为初学者打下坚实的基础。通过一系列精心设计的实例,我们将引导您快速掌握awk的基础知识。这些实例不仅有助于理解理论,还能让您在实践中加深印象。此外,结合作者在实际工作中积累的丰富经验,我们将分享一些实用的awk应用案例,旨在帮助您更深入地掌握这一工具的高级用法。无论您是初学者还是希望提升技能的资深用户,本章节都将为您提供宝贵的学习资源。
不管是那一门编程语言,字符串类型都是及其重要的,所以在学习各种编程语言后会发现近40%左右都与字符串有关, 特别是在 php、java、python 编程中可以将数据进行筛选输出,在Shell中可以awk工具并且自定义函数进行输出各种样式,使用awk将会使我们在运维中可以更加的简单简便处理的数据, 所以这也是我们必须要学习并掌握 awk 命令的原因。
本文是作者花费一定的时间,从学习、运维开发工作中总结而来,让各位初学者可以快速了解使用awk命令进行更加复杂的内容编辑、替换、计算、过滤输出,使之看友们可以快速应用在运维工作,这也是作者的初衷,如果感觉此文对你有帮助的话,就请多多支持作者【#运维从业必学】专栏。
Linux 运维学习之路相关文章:
Linux 运维 | 1.从零开始,服务器远程连接与基础命令学习实践
Linux 运维 | 2.从零开始,文件系统目录结构及文件目录管理学习实践
Linux 运维 | 3.从零开始,用户和用户组管理实践
Linux 运维 | 4.从零开始,文件目录特殊权限管理实践
Linux 运维 | 5.从零开始,编辑器之神 vi/vim 速成指南
Linux 运维 | 6.从零开始,Shell编程中正则表达式 RegExp 速成指南
运维学习 | Linux 命令大全,从A到Z
Linux 命令 | 运维必学,文件目录管理操作命令实践集锦
Linux 命令 | 运维必学,用户和组管理命令实践集锦
Linux 命令 | 每日一学,文件目录特殊权限相关命令集锦
Linux 命令 | 每日一学,文本处理之文件内容查看实践
Linux 命令 | 每日一学,文本处理之内容分割排序实践
Linux 命令 | 每日一学,文本处理之内容统计比较实践
Linux 命令 | 每日一学,文本处理三剑客之grep命令实践
Linux 命令:每日一学,文件查找之find命令实践
Linux 命令:每日一学,参数传递之xargs命令实践
Linux 命令:每日一学,一文说尽打包压缩工具实践
Linux 命令 | 每日一学,文本处理三剑客之sed命令实践
以自身实践为第一标准,下面跟随作者一起学习实践吧!
0x01 awk 命令 - 报告生成格式化输出
1.awk 简介
描述:awk(Aho,Weinberger,Kernighan)报告生成器,主要用于格式化文本输出,此工具包含在GUN/Linux发行版的系统中,目前由软件基金会(FSF)进行开发维护,所以也称为 GUN AWK (GAWK)。
awk 命令与其说它是一个命令,更不如说它是一门脚本编程语言,因为其既可以命令行的方式运行,也可使用脚本方式运行,它是可针对文本和数据进行处理的编程语言,它拥有多种发行版本,如:awk、nawk、gawk
。
awk :最先源于 AT & T 实验室发布的。
nawk :AT & T 实验室发布的 awk 的升级版本。
gawk :自由软件基金会发布的 GNU awk 版本,所有基于 GUN/Liunux 发行版中默认的 awk 与 nawk 是完全兼容的,这也是后续学习默认使用的版本。
awk 功能特点:
擅长对文本和数据进行灵活处理,并已自定义格式输出文本报表,
支持对数据排序、计算、统计功能,
支持脚本语言相关功能,例如变量、数组、函数、流程控制(顺序、条件、循环)等,这是它和C语言的相同之处。
支持用户使用动态正则表达式。
2.awk 语法格式
语法参数:
# 语法格式
awk [options] 'script' -v var=value file (s)
awk [options] -f scriptfile -v var=value file(s)
# 注:数据可以来自标准输入(stdin)、一个或多个文件,或其它命令的管道输出.# 常用参数
-F 'Format String' # 指定输入分隔符,fs可以是字符串或正则表达式,如-F:
-v var=value # 赋值一个用户定义变量,将外部变量传递给awk
-f scripfile # 编写的脚本文件中读取awk命令
-m[fr] val # 对val值设置内在限制,-mf 选项限制分配给val的最大块数目,-mr 限制记录的最大数目。
基础格式
awk 中的 script 或者叫 Program 通常是被放在单引号中,并可以由三部分组成: BEGIN 语句块、通用语句块(可使用模式匹配)、END 语句块。
# 格式
Pattren {Action Statements;.....}# 简约
awk 'BEGIN{ commands;print "start" } pattern { commands } END{ commands;print "end" }' file.txt# Pattren:决定动作语句何时触发及其触发条件,例如:BEGIN、pattern、END 以及/正则/、关系表达式、模式匹配表达式等。# BEIGIN : 在输入流读取之前被执行,可选语句,主要用于变量初始化,打印输出表格的表头等# Pattern : 在输入流读取第一行到末尾执行,可选语句,即每一行都会执行该语句块,所以也是文本处理最重要部分,若没有提供此语句块,则默认执行 print。# END : 在输入流中全部被读取处理完后执行,也是可选语句,主要将前面针对每行处理分析的结果进行归纳汇总输出。
# Action :包含了对数据如何处理,类似一个循环体,会对文件中的每一行进行迭,例如 print $1 带换行,printf 不带换行。# Input Statements : 输入声明# Output Statements : 输出声明,例如 print,printf# Expressions : 算术表达式、正则表达式# Compound Statements : 组合语句声明# Control Statements : 控制语句声明,例如 if,while
awk 工作流程
Step 1.执行 BEIGN { commands } 语句块中的语句,进行初始化准备相关操作。
Step 2.从文件或者管道符(标准输入)读取一行(默认以
\n
进行分隔行),然后执行 patter 语句块,逐行扫描运行直至文件被全部读取完毕。Step 3.当读取至输入流末尾时,执行 END 语句块中的语句,进行输出前的相关操作。
温馨提示:awk 必须有处理的文件或是通过管道符传入的字符串,否则会一直卡再输入状态,输入什么就会再次打印什么;
$ awk '{print $0}'
weiyigeek
weiyigeek
公众号:全栈工程师修炼指南
公众号:全栈工程师修炼指南
https://weiyigeek.top
https://weiyigeek.top
^c # Ctrl + C 停止输入
温馨提示:默认读取带有\n
行符分割的记录(即文件每一行),将记录按指定的域分隔符(默认以空格分隔
)划分域,填充域,则表示所有域即一行内容,1 表示第一个域,$n 表示第 n 个域。
温馨提示:若省略 Action Statements
部分,则默认执行 print $0
操作。
awk 控制语句
组合语句:
{Statements;....}
条件语句:
if(condition){Statements;..}
或者if(condition){Statements;..}else{Statements;..}
循环语句:
while (condition) {Statements;..}do {Statements;..} while (condition)for (expr1;expr2;expr3) {Statements;..}break continue
退出语句:
exit
其他语句:
next
awk 用户帮助手册:
https://www.gnu.org/software/gawk/manual/gawk.html
https://man7.org/linux/man-pages/man1/awk.1p.html
3.awk 学习指南
简单输出
描述:此小节将介绍 awk 命令中如何输出数据,包括:print、printf 命令的简单使用,固定字符需要用 "" 引用起来,而变量与数字则不需要。
# 换行
print item1,item2,...# 不会自动换行,且支持格式输出,与 C 语言中 printf 类似
printf "FORMAT",item1,item2,...
# 格式符
%s 字符串
%d,%i 十进制整数
%o,%O 八进制数
%x,%X 十六进数
%f 浮点数
%e,%E 指数形式
%c 显示字符ASCII码
%g,%G 科学计数法或者浮点数形式显示
%u 无符号整数
%% 输出一个百分号
# 修饰符
#.# 例如 3.2f 3 表示显示的最小位数,#2 表示小数点后的位数
- 左对齐,例如 %-15s
+ 显示数值前面的正负号
范例演示:
输出文本内容
# 单次文本内容
$ echo | awk '{print "Hello,World! awk"}'Hello,World! awk# 多次输出内容
seq 3 | awk '{print "Hello,World! awk"}'Hello,World! awkHello,World! awkHello,World! awk# 输出内容到文件
echo | awk '{print("Hello World! awk\n") >> "hello.txt"}';cat hello.txtHello World!
不同语句块内容输出
echo -e "A line 1\nA line 2" | awk 'BEGIN{ print "BEGIN" } { print } END{ print "END" }' #通过管道符号BEGINA line 1A line 2END
运算输出内容
echo | awk '{print 2 + 3}'5echo | awk '{print (2 + 3) * 2 - 5}'5
使用引号""拼接字符串输出
echo | awk '{ var1="v1"; var2="v2"; var3="v3"; print var1,var2,var3; }'
#v1 v2 v3echo | awk '{ var1="1"; var2="2"; var3="3"; print var1"=>"var2"=>"var3; }'
#1=>2=>3
输入指定列, 助 -F 选项确定分割符号进行指定列输出,默认的字段定界符是空格:
# 查看系统用户默认Shell类型
awk -F: '{print $1,$7}' /etc/passwd | head -n 3
# 或者 $NF 表示最后一列
awk -F: '{ print $1,$NF }' /etc/passwdroot /bin/bashbin /sbin/nologindaemon /sbin/nologin# 输出文件系统挂载点及挂载目录
grep -E -v "#|^$" /etc/fstab | awk '{print $1,$2}'/dev/mapper/klas-root /UUID=a9d27d62-baa2-426e-949e-e0553e04976a /bootUUID=ECA2-8909 /boot/efi/dev/mapper/klas-swap none# 输出用户ID并以 | 分隔
awk -F: '{print $1"|"$3}' /etc/passwd | head -n 3root|0bin|1daemon|2# 指定分隔符时包含在 [ ] 中的字符将作为分隔字符,而 [ , ] 字符不作为分隔符处理
echo "[weiyigeek.top]" | awk -F "[ .]" '{ print $2}'
top]
使用扩展正则分隔输出, 值得学习借鉴
# 面试题:取出分区利用率
df | awk -F '[[:space:]]+|%' '{print $1,$5}'
# 或者
df | awk -F ' +|%' '{print $1,$5}'文件系统 已用devtmpfs 0tmpfs 0tmpfs 2tmpfs 0/dev/mapper/klas-root 37tmpfs 1/dev/nvme0n1p2 29/dev/nvme0n1p1 2tmpfs 0tmpfs 0# 面试题:自定义提取指定硬盘设备的利用率
df | awk -F '[[:space:]]+|%' '/^\/dev/{print $1" -> "$7,$5}'/dev/mapper/klas-root -> / 37/dev/nvme0n1p2 -> /boot 29/dev/nvme0n1p1 -> /boot/efi 2# 面试题:统计当前系统正在使用连接端口以及来源IP数量
netstat -an | grep "ESTABLISHED" | grep -v "127.0.0.1" | awk -F "[ :]+" '{print $5,$6}' | sort | uniq -c
netstat -an | grep "ESTABLISHED" | awk -F "[ :]+" '{print $5,$6}' | sort |uniq -c6 127.0.0.11 183.232.94.2161 1521 10.20.172.1581 22 10.20.172.1031 42018 10.20.172.158# 面试题:取出ifconfig 命令结果中的 网卡和 IP 地址
ifconfig | awk -F ' +|:' '/netmask|UP/{print $1,$3}' | awk '{print $1}'
ens160
10.20.172.158
lo
127.0.0.1
温馨提示:在 awk 中脚本通常是被单引号'{ 命令 }'
或双引号"{ 命令 }"中
, 的 print 语句中双引号
是被当作拼接符使用,例如 '{ print $1"="$2}'
结果将以 =
分隔输出。
使用格式化占位符输出,常用值得学习借鉴
awk -F: '{printf "%s\n",$1}' /etc/passwd | head -n 3
awk -F: '{printf "%10s\n",$1}' /etc/passwd | head -n 3
awk -F: '{printf "%-10s\n",$1}' /etc/passwd | head -n 3
awk -F: '{printf "%-10s %10d\n",$1,$3}' /etc/passwd | head -n 3
awk -F: '{printf "user: %-18s , uid: %5d\n",$1,$3}' /etc/passwd | head -n 3# user: root , uid: 0# user: bin , uid: 1# user: daemon , uid: 2# ascii 字符输出
echo | awk 'BEGIN{printf "%c %d",65,"A"}'# A 0# 进制转换输出
echo | awk 'BEGIN{printf "%c %d %o %x \n",97,97,97,97;printf "%c %d %o %x \n",98,98,98,98}'a 97 141 61b 98 142 62
变量调用
描述:在 awk 中变量分为内置变量和自定义变量, 其中内置变量(预定义变量)包括:NR、NF、FILENAME、FS、RS、OFS、ORS、OFMT、ARGC、ARGV
等;自定义变量通常是在命令行中或在 BEGIN 和 END 块中定义调用,特别注意 awk 中变量区分大小写。
内置变量
描述:其中不同的发行版本的awk工具,支持的内置变量可能不同,建议查看 awk 帮助手册,这里作者也简单罗列部分:
# 不同 awk 发行版,简写缩写
[A] = awk
[N] = nawk
[P] = POSIXawk
[G] = gawk ,基本都兼容# 内置变量
$n 当前记录的第n个字段,比如n为1表示第一个字段,n为2表示第二个字段。
$0 这个变量包含执行过程中当前行的文本内容。
[N] ARGC # 命令行参数的数目。
[G] ARGIND # 命令行中当前文件的位置(从0开始算)。
[N] ARGV # 命令行参数的数组。
[G] CONVFMT # 数字转换格式(默认值为%.6g)。
[P] ENVIRON # 环境变量关联数组。
[N] ERRNO # 最后一个系统错误的描述。
[G] FIELDWIDTHS # 字段宽度列表(用空格键分隔)。
[A] FILENAME # 当前输入文件的名。
[P] FNR # 同NR,但相对于当前文件。
[A] FS # 字段分隔符(默认是任何空格)。
[G] IGNORECASE # 如果为真,则进行忽略大小写的匹配。
[A] NF # 表示字段数,在执行过程中对应于当前的字段数。常用
[A] NR # 表示记录数,在执行过程中对应于当前的行号。常用
[A] OFMT # 数字的输出格式(默认值是%.6g)。
[A] OFS # 输出字段分隔符(默认值是一个空格)。常用
[A] ORS # 输出记录分隔符(默认值是一个换行符)。
[A] RS # 记录分隔符(默认是一个换行符)。
[N] RSTART # 由match函数所匹配的字符串的第一个位置。
[N] RLENGTH # 由match函数所匹配的字符串的长度。
[N] SUBSEP # 数组下标分隔符(默认值是34)。
简单示例
位置参数变量:从 $0~{n} 开始,类似于 shell 中位置参数变量
# 1.输出第几列的数据
echo -e "1 2 3\n4 5 6\n7 8 9" | awk '{print $0," ==",$1,"-",$2,"-",$3}'
# 1 2 3 == 1 - 2 - 3
# 4 5 6 == 4 - 5 - 6
# 7 8 9 == 7 - 8 - 9# 2.打印每一行的第二和第三个字段:
echo -e "1 2 3\n4 5 6\n7 8 9" | awk '{ print $2,$3 }'
# 2 3
# 5 6
# 8 9
FS 变量 :默认为空白字符,功能相当于 -F 选项,注意同时使用时-F优先级最高。