AWK快速入门教程

2023-11-05

最近看到安装开源软件的相关脚本,其中大量用到AWK相关内容。本文介绍AWK的基础知识及典型用法、结合示例进行说明,方便备忘查询。了解awk基础知识将大大提高命令行上操作文本文件的能力。awk有几种不同的实现。我们将使用awk的GNU实现,它被称为gawk。在大多数Linux系统上,awk解释器只是gawk的符号链接。

记录和字段

Awk可以处理文本数据文件和流。输入数据分为记录和字段。Awk每次操作一条记录,直到到达输入的末尾。记录由一个称为记录分隔符的字符分隔。默认的记录分隔符是换行符,这意味着文本数据中的每一行都是一条记录。可以使用RS变量设置新的记录分隔符。

记录由字段分隔符分隔的字段组成。默认情况下,字段由空格分隔,包括一个或多个制表符、空格和换行符。

每个记录中的字段由美元符号($)引用,后面跟着以1开头的字段号。第一个字段用$1表示,第二个字段用 2 表示,以此类推。最后一个字段也可以用特殊变量 2表示,以此类推。最后一个字段也可以用特殊变量 2表示,以此类推。最后一个字段也可以用特殊变量NF来引用。可以用$0引用整个记录。

下面是如何引用记录和字段的可视化表示:

tmpfs      788M  1.8M  786M   1% /run/lock 
/dev/sda1  234G  191G   31G  87% /
|-------|  |--|  |--|   |--| |-| |--------| 
   $1       $2    $3     $4   $5  $6 ($NF) --> fields
   
|-----------------------------------------| 
                    $0                     --> record

AWK 程序

要用awk处理文本,需要编写一个程序,告诉命令该做什么。该程序由一系列规则和用户定义的函数组成。每个规则包含一个模式和操作对。规则之间用换行符或分号(;)分隔。通常,awk程序是这样的:

pattern { action }
pattern { action }
...

当awk处理数据时,如果模式与记录匹配,它就对该记录执行指定的操作。当规则没有模式时,匹配所有记录(行)。

awk动作用大括号({})括起来,由语句组成。每个语句指定要执行的动作。一个动作可以有多个语句,用换行符或分号(;)分隔。如果规则没有动作,则默认打印整个记录。

Awk支持不同类型的语句,包括表达式、条件、输入、输出语句等等。最常见的awk语句有:

  • exit - 停止执行整个程序并结束.
  • next - 停止处理当前记录并移至输入数据的下一条记录.
  • print - 打印记录、字段、变量以及自定义文本.
  • printf - 对输出格式进行更多的控制,类似C语言的 printf .

在编写awk程序时,在井号(#)之后直到行尾的所有内容都被认为是注释。可以使用延续字符反斜杠()将长行分成多行。

执行AWK程序

awk程序可以以几种方式运行。如果程序很短很简单,可以直接在命令行上传递给awk解释器:

awk 'program' input-file...

当在命令行上运行程序时,它应该用单引号(")括起来,这样shell就不会解释该程序。

如果程序又大又复杂,最好把它放在一个文件中,然后使用-f选项将文件传递给awk命令:

awk -f program-file input-file...

在下面的例子中,我们将使用一个名为“teams.txt”的文件,内容如下所示:

Bucks Milwaukee    60 22 0.732 
Raptors Toronto    58 24 0.707 
76ers Philadelphia 51 31 0.622
Celtics Boston     49 33 0.598
Pacers Indiana     48 34 0.585

awk模式

awk中的模式控制是否应该执行关联的操作。Awk支持不同类型的模式,包括正则表达式、关系表达式、范围和特殊表达式模式。当规则没有模式时,将匹配每个输入记录。下面是一个只包含一个动作的规则示例:

awk '{ print $3 }' teams.txt

程序将打印每条记录的第三个字段:

60
58
51
49
48

正则表达式

正则表达式或正则表达式是匹配一组字符串的模式。Awk正则表达式模式用斜杠(//)括起来:

/regex pattern/ { action }

最基本的例子是文字字符或字符串匹配。例如,要显示每条包含“0.5”的记录的第一个字段,您可以运行以下命令:

awk '/0.5/ { print $1 }' teams.txt
# 输出结果

Celtics
Pacers

模式可以是任何类型的扩展正则表达式。下面是一个示例,如果记录以两个或两个以上数字开头,则打印第一个字段:

awk '/^[0-9][0-9]/ { print $1 }' teams.txt
## 输出
76ers

关系表达式

关系表达式模式通常用于匹配特定字段或变量的内容。

默认情况下,将根据记录匹配正则表达式模式。要将正则表达式与字段匹配,请指定字段并对模式使用“包含”比较运算符(~)。

例如,要打印第二个字段包含“ia”的每条记录的第一个字段,您可以输入:

awk '$2 ~ /ia/ { print $1 }' teams.txt

# output
76ers
Pacers

要匹配不包含给定模式的字段,请使用!~操作符:

awk '$2 !~ /ia/ { print $1 }' teams.txt
# output
Bucks
Raptors
Celtics

可以比较字符串或数字的关系,如大于、小于、等于等。下面的命令打印第三个字段大于50的所有记录的第一个字段:

awk '$3 > 50 { print $1 }' teams.txt
#  output
Bucks
Raptors
76ers

范围模式

范围模式有两个逗号分隔的独立模式组成:

pattern1, pattern2

从匹配第一个模式的记录开始的所有记录,直到匹配第二个模式的记录。下面是一个示例,它将打印所有记录的第一个字段,从包含“Raptors”的记录开始,直到包含“Celtics”的记录:

awk '/Raptors/,/Celtics/ { print $1 }' teams.txt
# output
Raptors
76ers
Celtics

该模式也支持关系表达式。下面的命令将打印从第四个字段等于32开始的所有记录,直到第四个字段等于33的记录:

awk '$4 == 31, $4 == 33 { print $0 }' teams.txt
# output
76ers Philadelphia 51 31 0.622
Celtics Boston     49 33 0.598

范围模式不能与其他模式表达式组合。

特殊表达式模式

Awk包括以下特殊模式:

BEGIN -用于在处理记录之前执行操作。

END -用于在记录处理后执行操作。

BEGIN模式通常用于设置变量,END模式用于处理记录(如计算)中的数据。

下面的示例将打印“Start Processing”。,然后打印每条记录的第三个字段,最后打印“End Processing”:

awk 'BEGIN { print "Start Processing." }; { print $3 }; END { print "End Processing." }' teams.txt
# output
Start Processing
60
58
51
49
48
End Processing.

如果程序只有BEGIN模式,则执行操作,而不处理输入。如果程序只有END模式,则在执行规则操作之前处理输入。

awk的Gnu版本还包括两个更特殊的模式BEGINFILE和ENDFILE,它们允许您在处理文件时执行操作。

组合模式

Awk允许您使用逻辑与操作符(&&)和逻辑或操作符(||)组合两个或多个模式。

下面是一个使用&&运算符打印第三个字段大于50且第四个字段小于30的记录的第一个字段的示例:

awk '$3 > 50 && $4 < 30 { print $1 }' teams.txt
# output
Bucks
Raptors

内置变量

Awk有许多内置变量,其中包含有用的信息,并允许您控制程序的处理方式。下面是一些最常见的内置变量:

  • NF - 记录的字段数.
  • NR - 当前记录编号.
  • FILENAME - 当前正在处理的输入文件的名称.
  • FS - 字段分隔符.
  • RS - 记录分隔符.
  • OFS - 输出字段分隔符.
  • ORS - 输出记录分隔符.

下面是一个显示如何打印文件名和行数(记录)的示例:

awk 'END { print "File", FILENAME, "contains", NR, "lines." }' teams.txt
#output
File teams.txt contains 5 lines.

AWK中的变量可以在程序中的任何一行设置。要为整个程序定义一个变量,请将其放在BEGIN模式中。

改变记录和字段的分隔符

字段分隔符的默认值是任意数量的空格或制表符。它可以通过在FS变量中设置来更改。

例如,将字段分隔符设置为。你可以用:

awk 'BEGIN { FS = "." } { print $1 }' teams.txt
#output
Bucks Milwaukee    60 22 0
Raptors Toronto    58 24 0
76ers Philadelphia 51 31 0
Celtics Boston     49 33 0
Pacers Indiana     48 34 0

字段分隔符也可以设置为多个字符:

awk 'BEGIN { FS = ".." } { print $1 }' teams.txt

当在命令行上运行awk一行程序时,您还可以使用-F选项来更改字段分隔符:

awk -F "." '{ print $1 }' teams.txt

默认情况下,记录分隔符是一个换行符,可以使用RS变量进行更改。

下面是一个演示如何将记录分隔符更改为。的示例:

awk 'BEGIN { RS = "." } { print $1 }' teams.txt
# output
Bucks Milwaukee    60 22 0
732 
Raptors Toronto    58 24 0
707 
76ers Philadelphia 51 31 0
622
Celtics Boston     49 33 0
598
Pacers Indiana     48 34 0
585

awk 动作

Awk操作被括在大括号({})中,并在模式匹配时执行。一个操作可以有零条或多条语句。多条语句按照它们出现的顺序执行,并且必须用换行符或分号(;)分隔。

awk中支持几种类型的操作语句:

  • 表达式,如变量赋值、算术运算符、自增和自减运算符。
  • 控制语句,用于控制程序的流程(if、for、while、switch等)。
  • 输出语句,如print和printf。
  • 复合语句,用于组合其他语句。
  • 输入语句,用于控制输入的处理。
  • 删除语句,用于删除数组元素。

print语句可能是最常用的awk语句。它打印文本、记录、字段和变量的格式化输出。

打印多个项目时,需要用逗号分隔。下面是一个例子:

awk '{ print $1, $3, $5 }' teams.txt
# output
Bucks 60 0.732
Raptors 58 0.707
76ers 51 0.622
Celtics 49 0.598
Pacers 48 0.585

如果不带参数使用print,则默认打印$0。打印当前记录。

要打印自定义文本,必须用双引号对文本进行引用:

awk '{ print "The first field:", $1}' teams.txt
# output
The first field: Bucks
The first field: Raptors
The first field: 76ers
The first field: Celtics
The first field: Pacers

也可以打印特殊字符,如换行符:

awk 'BEGIN { print "First line\nSecond line\nThird line" }'
# output
First line
Second line
Third line

printf语句提供了对输出格式控制。下面是插入行号的示例:

awk '{ printf "%3d. %s\n", NR, $0 }' teams.txt
# output
  1. Bucks Milwaukee    60 22 0.732 
  2. Raptors Toronto    58 24 0.707 
  3. 76ers Philadelphia 51 31 0.622
  4. Celtics Boston     49 33 0.598
  5. Pacers Indiana     48 34 0.585

下面的命令计算每行第三个字段中存储的值的总和:

awk '{ sum += $3 } END { printf "%d\n", sum }' teams.txt
# output 
266

下面是另一个例子,展示了如何使用表达式和控制语句来打印从1到5的数字的平方:

awk 'BEGIN { i = 1; while (i < 6) { print "Square of", i, "is", i*i; ++i } }'
#output
Square of 1 is 1
Square of 2 is 4
Square of 3 is 9
Square of 4 is 16
Square of 5 is 25

像上面这样的单行命令更难理解和维护。当编写较长的程序时,你应该创建一个单独的程序文件:

# prg.awk

BEGIN { 
  i = 1
  while (i < 6) { 
    print "Square of", i, "is", i*i; 
    ++i 
  } 
}

通过将文件名传递给awk解释器来运行程序:

awk -f prg.awk

你也可以通过使用shebang指令和设置awk解释器来将awk程序作为可执行文件运行:

prg.awk 文件内容:

#!/usr/bin/awk -f
BEGIN { 
  i = 1
  while (i < 6) { 
    print "Square of", i, "is", i*i; 
    ++i 
  } 
}

保存文件并设置可执行:

chmod +x prg.awk
# 现在直接执行
./prg.awk

在Awk程序中使用Shell变量

如果在shell脚本中使用awk命令,那么很可能需要向awk程序传递一个shell变量。一种选择是用双引号而不是单引号括起程序,并替换程序中的变量。然而,这个选项将使您的awk程序更加复杂,因为您需要转义awk变量。

在awk程序中使用shell变量的推荐方法是将shell变量赋值给awk变量。下面是一个例子:

$ num=51
$ awk -v n="$num" 'BEGIN {print n}'
# output
51

总结

Awk是最强大的文本操作工具之一,本文仅仅介绍了awk编程语言的皮毛。要了解更多关于awk的信息,请查看官方Gawk文档。参考文档:Awk Command in Linux with Examples | Linuxize

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

AWK快速入门教程 的相关文章

  • 使用vim,如何快速刷新正在处理的网页?

    我已经使用 VIM 几个星期了 同时处理各种网络语言 我真的很喜欢它 我发现必须点击或单击浏览器并刷新页面才能看到代码更改的效果 这很麻烦 更烦人的是 因为我使用的是 Virtual Box 而且我倾向于在主机系统上处理 PDF 文件 因此
  • Motif 库的水平绘制的 RowColumn 类 (C)?

    我正在使用 Motif Library 来完成我的工作 如果有人不熟悉这个库 您可以在这里找到文件列表https packages ubuntu com xenial amd64 libmotif dev filelist https pa
  • 使用 Python for Linux 模拟按键事件

    我正在编写一个脚本来自动运行特定模型 当模型失败时 它会等待用户输入 Enter 键 我可以检测到模型何时失败 但我无法使用 python 在 Linux 上 来模拟按键事件 Windows 有 SendKeys 库来执行此操作 但我想知道
  • 32 位 x86 汇编中堆栈对齐的职责

    我试图清楚地了解谁 调用者或被调用者 负责堆栈对齐 64 位汇编的情况相当清楚 它是由caller 请参阅系统 V AMD64 ABI 第 3 2 2 节栈帧 输入参数区域的末尾应按 16 对齐 32 如果 m256 在堆栈 字节边界上传递
  • UNIX 域 STREAM 和 DATAGRAM 套接字之间的区别?

    这个问题是NOTSTREAM 类型和 DATAGRAM 类型 INTERNET 套接字之间的区别 我知道 STREAM 套接字使用 TCP 数据报套接字使用 UDP 以及所有 TCP UDP 内容 按顺序到达的数据包 ACK NACK 等
  • Linux 堆栈大小

    我正在寻找 Linux 内核中堆栈的良好描述 但我发现找到任何有用的东西出奇地困难 我知道大多数系统的堆栈限制为 4k 而其他系统则限制为 8k 我假设每个内核线程 下半部分都有自己的堆栈 我还听说 如果中断发生 它会使用当前线程的堆栈 但
  • 如何解决错误:psycopg2 构建轮失败?

    我遇到问题了psycopg2 的构建轮子 thru pip install r requirements txt 我使用的是 ubuntu 20 04 python 3 8 5 venv 这是我的要求 txt amqp 2 6 1 anyj
  • 复制稀疏文件

    我正在尝试了解 Linux UNIX 低级接口 作为练习 我想编写一个代码 将一个有漏洞的文件复制到一个新文件 同样有漏洞 所以我的问题是 如何从第一个文件读取 而不是直到第一个洞 而是直到文件的最后 如果我没错的话 read 当到达第一个
  • 为什么运行一个空程序需要这么多指令?

    所以最近我了解到perfLinux 中的命令 我决定进行一些实验 因此我创建了一个空的 C 程序并测量了运行所需的指令数 echo int main gt emptyprogram c gcc O3 emptyprogram c o emp
  • x = os.system(..) 的返回值[重复]

    这个问题在这里已经有答案了 当我打字时os system whoami 在Python中 作为root 它返回root 但是当我尝试将它分配给变量时x os system whoami 它将 x 的值设置为 0 为什么 os system
  • 如何从 Windows 反编译 Linux 二进制文件?

    如何从 Windows 反编译 Linux 二进制文件 so 谢谢 你可以试试回旋镖 http boomerang sourceforge net 您需要首先从源代码构建它 因为提供的二进制文件不涵盖这种情况 如果您绝对拒绝编译任何内容 请
  • 将 React 应用程序作为后台进程运行

    我对部署前端代码完全陌生 因此提出了这个问题 我有一个 React 应用程序 需要作为后台进程运行 但是我对如何执行此操作有点困惑 我运行一个 npm 脚本 npm run build 在服务器上构建 缩小和服务项目 构建过程的相关代码是这
  • 编译JNI时出现问题

    我通过引用已使用 JNI 生成的头文件实现了以下 C 代码 include
  • (Linux) 如何在没有显示环境的情况下运行gtk程序? Gtk-警告 **:无法打开显示:

    我有一个必须在 GTK gui 环境中运行的程序 我只能使用ssh 该程序将在服务器 centos 6 上运行并安装 gnome X 显示 不需要看GUI 但运行完成后 我就能得到答案 VNC 和远程屏幕已禁用 当我在 ssh 中启动程序时
  • 为什么 bash 无法识别套接字文件的存在

    在 Linux 机器上 我想检查特定的套接字文件是否存在 我知道套接字文件存在 但我在 bash 中的检查没有向我显示这一点 ls l var run supervisor sock srwxrw rw 1 root root 0 Jun
  • 什么可能导致 sock send() 命令上的“资源暂时不可用”

    什么会导致Resource temporarily unavailable套接字上的错误send 命令 套接字设置为AF UNIX SOCK STREAM 它在大多数情况下都有效 但偶尔会出现此错误 套接字的接收端似乎工作正常 我知道这不是
  • 找到 32 位 ELF Linux 二进制文件结束和填充开始的位置?

    如何确定 32 位 ELF Linux 二进制文件的结束位置以及附加到文件的其他数据的开始位置 例如 某些软件会将数据附加到文件末尾以供提取或执行 同时包含在单个二进制文件中 自解压存档就是此类文件的一个示例 我想做的事情类似于通过PE头找
  • 如何使用 sed 或 awk 根据开始子字符串和结束子字符串提取行部分

    我有一个多行文件 其中的文本没有空格 Thereisacat whichisverycute Thereisadog whichisverycute Thereisacat whichisverycute Thereisadog which
  • 在 Linux 上用 C 跟踪键盘和鼠标事件

    如何在 Linux 中用 C 语言跟踪键盘或鼠标事件 Like for example if the user presses ESC Shift etc I should be able to track it Same way for
  • 如何在 python setup.py 中 chmod 文件?

    我使用 setup py 创建了一个 python 包安装 我希望它复制文件夹 为临时创建的 did 中的数据文件 问题是我必须使用 sudo 权限调用 setup py 因为它写入 usr local 因此 当我的数据文件复制到 did

随机推荐

  • 7. 从0学ARM-GNU伪指令、代码编译,lds使用

    嵌入式工程师到底要不要学习ARM汇编指令 arm学习文章汇总 到底什么是Cortex ARMv8 arm架构 ARM指令集 soc 一文帮你梳理基础概念 科普 关于ARM指令用到的IDE开发环境可以参考下面这篇文章 1 从0开始学ARM 安
  • 黑客帝国效果页面

    效果图如下 代码如下
  • Docker学习研究笔记(三)

    Docker安装 Docker 支持以下的centos 版本 Centos 7 64 bit Centos 6 5 64 bit 目前 centos 仅发行版本的内容支持 docker Docker 运行在 centos 7上 要求系统为6
  • 52道常见Python面试题,你来试一试?

    最近有很多人找小编询问python求职面试的一些情况 python岗位众多 面试官的个性也千人千面 其实是没有固定的套路的 还是一句老话 要成功拿下一个重要的面试 靠的是 台上三分钟 台下几年功 小编虽然没有套路 但是有干货呀 最近整理近一
  • gcc常用选项及常见的文件格式,扩展名

    gcc常用选项 编译过程 预处理 编译 汇编 链接 gcc的选项 必须分开给出 x 语言名 指出后面文件的语言 c 编译 汇编源文件 生成目标文件 S 编译不汇编 生成汇编文件 E 预处理 输出送到标准输出 o 指定输出的文件名 pipe
  • ext4 delay allocation之ext4_writepages页回写源码剖析

    概述 ext4 write写入pagecache之后 再合适的时机会回写到磁盘 ext4文件系统中是通过ext4 writepages写入磁盘 本来将在源码角度分析该过程 建议先参照ext4 delay allocation数据结构 ngi
  • 2022尚硅谷SSM框架跟学(三)MyBatis基础三

    2022尚硅谷SSM框架跟学 三 MyBatis基础三 9 动态SQL 9 1if 9 2where 方法一 加入恒成立的条件 方法二 使用where标签 9 3trim 9 4choose when otherwise 9 5foreac
  • Hive中运行任务报错:Error during job, obtaining debugging information...

    错误 Ended Job job 1545829388777 0070 with errors Error during job obtaining debugging information FAILED Execution Error
  • 华为od机考题目-分苹果

    A B两个人把苹果分成两队 A希望按照他的计算规则等分苹果 他的计算规则时按照二进制加法计算的 并且不计算走位 B的计算规则时十进制加法 包括正常进位 B希望在满足A的情况下获得苹果的重量最多 输入苹果的数量和每个苹果的重量 输出满足A的情
  • 编写程序,输入一个1~7之间的整数,输出该数字对应星期的英文单词。若数字超出范围,输出相应的提示信息。

    编写程序 输入一个1 7之间的整数 输出该数字对应星期的英文单词 若数字超出范围 输出相应的提示信息 例如 输入1输出Monday 输入7输出Sunday 运行结果示例1 运行结果示例2 运行结果示例3 1 7 8 Monday Sunda
  • 真题详解(补码转换)-软件设计(七十四)

    真题详解 索引查询 软件设计 七十三 https blog csdn net ke1ying article details 130659024 Composite模式 以树形结构来表示 整体 部分 的关系 使得单个和团体的使用都具有一致性
  • unity3d asset store 的资源下载到本地的目录

    之前一直不知道unity3d asset stored额资源下载在本地什么目录的 也不知道是不是我用的破解版的原因 下载的资源有一部分导入不成功 包解压错误的消息 我确定是没有中文目录 但是一直无解 本地目录也找不到 照成我长期没办法用as
  • 别踩坑!使用MySQL唯一索引请注意

    背景 在程序设计中 我们往往需要确保数据的唯一性 比如在常见的注册模块 我们需要确保一个手机号只能注册为一个账号 这种情况下 我们的程序往往是第一道关卡 用户来注册之前 首先判断这个手机号是否已经注册 如果已经注册则返回错误信息 或直接去登
  • 122-124

    7 123 冬奥会的好项目 滑雪 while True try R C map int input split mat 高度矩阵 dic 记录每一个高度在矩阵中的位置 ele list 所有高度组成的列表 solution 解矩阵 表示到达
  • 【yarn】yarn客户端与服务端通讯协议ApplicationClientProtocol

    文章目录 1 概述 1 1 应用信息 1 2 资源信息 1 3 集群 节点 配置信息 1 4 队列信息 1 概述 上一篇文章 Yarn yarn源码阅读之ClientRMService 在一篇文章中 我们看到了在创建服务端ClientRMS
  • PHP计算机毕设题目大全

    源码 最新仿金蝶电商ERP进销存系统多仓库版带扫描功能 php网页版BS 14110100931郭婧 旅游网站 1626考勤管理系统 172酒店管理jhne434程序论文 320办公人事亢 413学生社团管理系统Y1A9程序 428志愿者信
  • 怎样访问远程服务器文件夹,访问远程服务器的共享文件夹

    访问远程服务器的共享文件夹 内容精选 换一换 FOTA升级作用 在官方更新新固件后 模组设备无需寄回给官方 而是通过远程FTP HTTP进行OTA升级固件 以更新新固件版本 从而达到更新设备的功能 BUG修复 本次我采用FPT的方式来升级L
  • Hashtable vs ConcurrentHashMap

    来源 黑马教程 Hashtable vs ConcurrentHashMap 要求 掌握 Hashtable 与 ConcurrentHashMap 的区别 掌握 ConcurrentHashMap 在不同版本的实现区别 Hashtable
  • 关于python 的空的__init__.py文件的作用,可不可以删除,到底有没有用?

    0 声明 本篇只讨论空 init py文件的情况 不顾前提非得说 init py文件里面也可以写东西的不在此讨论了范围之内 重点是个 空 字 1 很多地方的文件夹都有 init py 网上一般都说 有了这个东西会把它当作一个包 否则impo
  • AWK快速入门教程

    最近看到安装开源软件的相关脚本 其中大量用到AWK相关内容 本文介绍AWK的基础知识及典型用法 结合示例进行说明 方便备忘查询 了解awk基础知识将大大提高命令行上操作文本文件的能力 awk有几种不同的实现 我们将使用awk的GNU实现 它