Linux文本处理三剑客:awk

在Linux操作系统中,grep、sed、awk被称为文本操作"三剑客",上两期中,我们将详细介绍grep、sed的基本使用方法,希望能够帮助到有需要的朋友,现在,我们继续学习awk。

虽然awk是一个Linux中常见的命令,但确切的说,awk是一门编程语言。

要讲起来真的十分复杂,网上有很多教程,讲的都很棒的,但是也讲得很迷糊。

我也是在摸索中学习,尽量讲清晰一些,希望您在看的过程中,能够有所发现。

首先上官方手册:Gawk - GNU Project - Free Software Foundation (FSF)

1、awk简介

gawk - pattern scanning and processing language(模式扫描和处理语言)。AWK 的名称是由它们设计者的名字缩写而来 ------Afred Aho, Peter Weinberger与Brian Kernighan。

1.1 语法

awk [options] file ...

gawk [ POSIX or GNU style options ] -f program-file [ -- ] file ...
gawk [ POSIX or GNU style options ] [ -- ] program-text file ...

pgawk [ POSIX or GNU style options ] -f program-file [ -- ] file ...
pgawk [ POSIX or GNU style options ] [ -- ] program-text file ...

dgawk [ POSIX or GNU style options ] -f program-file [ -- ] file ...

可以看到,awk有几种版本,包括GAWK、pgawk、dgawk 。GAWK完全兼容 AWK 与 NAWK

1.2 描述

gawk 是 GNU 项目对 AWK 编程语言的实现。它符合 POSIX 1003.1 标准中对该语言的定义。该版本又基于 Aho、Kernighan 和 Weinberger 合著的《AWK 编程语言》一书中的描述。gawk 提供了当前版本 UNIX awk 中的一些附加功能以及许多 GNU 特有的扩展。命令行由 gawk 自身的选项、AWK 程序文本(如果没有通过 -f 或 --file 选项提供)以及要在预定义 AWK 变量 ARGC 和 ARGV 中使用的值组成。
pgawk 是 gawk 的性能分析版本。除了程序运行速度较慢并且在完成后自动在 awkprof.out 文件中生成执行性能分析报告之外,它在其他方面都与 gawk 完全相同。请参阅下面 --profile 选项的说明。
dgawk 是一个 awk 调试器。它不会直接运行程序,而是加载 AWK 源代码,然后提示输入调试命令。与 gawk 和 pgawk 不同,dgawk 只处理使用 -f 选项提供的 AWK 程序源代码。调试器在《GAWK: 高效 AWK 编程》一书中有详细介绍。

1.3 工作流程

awk语言的工作流程如上所示,分为三块为:BEGIN块、BODY块和END块。

BEGIN块开始,循环执行BODY块,最后执行END块。

开始块(BEGIN block)

开始块的语法格式如下所示:

BEGIN {awk-commands}

程序启动执行BEGIN块代码部分,BEGIN块在整个过程中只执行一次。BEGIN 是 AWK 的关键字,因此它必须是大写的。BEGIN块是可选的,可以没有BEGIN块部分。注意,awk代码块使用 {} 花括号整合一个块。

主体块(Body Block)

主体部分的语法要求如下:

/pattern/ {awk-commands}
复制代码
对于每一个输入的行都会执行一次主体部分的命令。默认情况下,对于输入的每一行,AWK 都会很执行命令。但是,我们可以将其限定在指定的模式中。 注意,在主体块部分没有关键字存在。

结束块(END Block)

下面是结束块的语法格式:

END {awk-commands}
复制代码
结束块是在程序结束时执行的代码。 END 也是 AWK 的关键字,它也必须大写。 与开始块相似,结束块也是可选的。

1.4 一个简单的例子

先创建一个名为 file1.txt 的文件。

Jan	13	25	15	115
Feb	15	32	24	226
Mar	15	24	34	228
Apr	31	52	63	420
May	16	34	29	208
Jun	31	42	75	492
Jul	24	34	67	436
Aug	15	34	47	316
Sep	13	55	37	277
Oct	29	54	68	525
Nov	20	87	82	577
Dec	17	35	61	401

使用下面的awk代码,

$ awk 'BEGIN{printf "月份\t年\t日\t年份\t版本\n"} {print}' file1.txt

执行以上命令,输出结果如下:

月份    年      日      年份    版本
Jan	13	25	15	115
Feb	15	32	24	226
Mar	15	24	34	228
Apr	31	52	63	420
May	16	34	29	208
Jun	31	42	75	492
Jul	24	34	67	436
Aug	15	34	47	316
Sep	13	55	37	277
Oct	29	54	68	525
Nov	20	87	82	577
Dec	17	35	61	401

对于这句代码,awk'BEGIN{printf "月份\t年\t日\t年份\t版本\n"} {print}' file1.txt,我们简单解释一下:

程序开始执行时,AWK 在开始块中读到了"BEGIN" 这个关键词,执行花括号里面的内容,输出表头信息。在主体块中,AWK 每读入一行就将读入的内容输出至标准输出流中,一直循环到整个文件被全部读入为止。

awk 程序指令
' ' awk程序块
BEGIN 开始块
{...} awk开始块的程序
printf 指定格式输出
" " printf的输出内容
\t 制表符
\n 换行符
{print} 主体块,简单输出

这里还涉及到两个知识点,printf和print
这里大概讲一下,前面的 printf 是为了控制宽度、精度采用,而后面的 print 只需要简单的输出数据而已。

2、awk常用参数

常用参数:
-c:使用兼容模式
-C:显示版权信息
-e:指定源码文件
-f:从脚本中读取 awk 命令
-F:设置输入时的字段分隔符
-v:自定义变量信息
-h:显示帮助信息
-m:对指定值进行限制

3、awk的变量

ARGC 
表示在命令行提供的参数的个数。
ARGV 
这个变量表示存储命令行输入参数的数组。数组的有效索引是从 0 到 ARGC-1。
CONVFMT
此变量表示数据转换为字符串的格式,其默认值为 %.6g。
ENVIRON
此变量是与环境变量相关的关联数组变量。
FILENAME
此变量表示当前文件名称。
FS
此变量表示输入的数据域之间的分隔符,其默认值是空格。 你可以使用 -F 命令行选项改变它的默认值。
NF
此变量表示当前输入记录中域的数量。
NR
此变量表示当前记录的数量。(译注:该变量类似一个计数器,统计记录的数量)
FNR
该变量与 NR 类似,不过它是相对于当前文件而言的。此变量在处理多个文件输入时有重要的作用。每当从新的文件中读入时 FNR 都会被重新设置为 0。
OFMT
此变量表示数值输出的格式,它的默认值为 %.6g。

示例:

还是原来file1.txt这张表:

Jan	13	25	15	115
Feb	15	32	24	226
Mar	15	24	34	228
Apr	31	52	63	420
May	16	34	29	208
Jun	31	42	75	492
Jul	24	34	67	436
Aug	15	34	47	316
Sep	13	55	37	277
Oct	29	54	68	525
Nov	20	87	82	577
Dec	17	35	61	401

对于awk而言,变量就是列,用$符号来表示,比如下面的内容:

$ awk '{print $1}' file1.txt

这里 $1,表示输出第一列,输入如下:

Jan
Feb
Mar
Apr
May
Jun
Jul
Aug
Sep
Oct
Nov
Dec

要是使用下面的代码:

$ awk -F: '{print $1}' file1.txt

输出:

Jan	13	25	15	115
Feb	15	32	24	226
Mar	15	24	34	228
Apr	31	52	63	420
May	16	34	29	208
Jun	31	42	75	492
Jul	24	34	67	436
Aug	15	34	47	316
Sep	13	55	37	277
Oct	29	54	68	525
Nov	20	87	82	577
Dec	17	35	61	401
复制代码
这里,-F:设置输入时的字段分隔符。

要是使用下面的代码:

$ awk -F: '{print $1,$NF}' file1.txt
复制代码
输出:
Jan     13      25      15      115 Jan 13      25      15      115
Feb     15      32      24      226 Feb 15      32      24      226
Mar     15      24      34      228 Mar 15      24      34      228
Apr     31      52      63      420 Apr 31      52      63      420
May     16      34      29      208 May 16      34      29      208
Jun     31      42      75      492 Jun 31      42      75      492
Jul     24      34      67      436 Jul 24      34      67      436
Aug     15      34      47      316 Aug 15      34      47      316
Sep     13      55      37      277 Sep 13      55      37      277
Oct     29      54      68      525 Oct 29      54      68      525
Nov     20      87      82      577 Nov 20      87      82      577
Dec     17      35      61      401 Dec 17      35      61      401
复制代码

这里,NF此变量表示当前输入记录中域的数量。

还有很多内容,包括循环、条件、运算、函数等,篇幅有限,看后期大家是否需要,如果需要的话,关注我,联系我更新。

如果您觉得有些用处,欢迎在评论区留言,关注。谢谢您的阅读!

往期学习笔记:

Windows系统开启Linux子系统(Ubuntu)

Linux常用命令(目录操作命令)

Linux常用命令:文件的创建、复制、移动、查找和删除命令

Linux常用命令:文本文件的查看与编辑

Linux常用命令:文本文件的拼接与分割

Linux常用命令:文件的权限管理

Linux常用命令:文件的下载、压缩与解压

Linux常用命令:常见的操作符

Linux常用命令:系统操作命令

Linux文本处理三剑客:grep

Linux文本处理三剑客:sed

相关推荐
wowocpp1 小时前
查看 linux ubuntu 分区 和 挂载 情况 lsblk
linux·运维·ubuntu
wowocpp1 小时前
查看 磁盘文件系统格式 linux ubuntu blkid ext4
linux·数据库·ubuntu
龙鸣丿2 小时前
Linux基础学习笔记
linux·笔记·学习
耶啵奶膘3 小时前
uniapp-是否删除
linux·前端·uni-app
_.Switch4 小时前
高级Python自动化运维:容器安全与网络策略的深度解析
运维·网络·python·安全·自动化·devops
2401_850410834 小时前
文件系统和日志管理
linux·运维·服务器
JokerSZ.4 小时前
【基于LSM的ELF文件安全模块设计】参考
运维·网络·安全
XMYX-05 小时前
使用 SSH 蜜罐提升安全性和记录攻击活动
linux·ssh
芯盾时代5 小时前
数字身份发展趋势前瞻:身份韧性与安全
运维·安全·网络安全·密码学·信息与通信
心灵彼岸-诗和远方6 小时前
DevOps业务价值流:架构设计最佳实践
运维·产品经理·devops