这个系列的第二篇,我们会学习字段,记录和一些非常有用的 Awk 变量。-- Seth Kenlon

Awk 有好几个变种:最早的 awk,是 1977 年 AT&T 贝尔实验室所创。它还有一些重构版本,例如 mawknawk。在大多数 Linux 发行版中能见到的,是 GNU awk,也叫 gawk。在大多数 Linux 发行版中,awk 和 gawk 都是指向 GNU awk 的软链接。输入 awk,调用的是同一个命令。GNU awk 用户手册中,能看到 awk 和 gawk 的全部历史。

这一系列的第一篇文章 介绍了 awk 命令的基本格式:

$ awk [选项] '模式 {动作}' 输入文件

awk 是一个命令,后面要接选项 (比如用 -F 来定义字段分隔符)。想让 awk 执行的部分需要写在两个单引号之间,至少在终端中需要这么做。在 awk 命令中,为了进一步强调你想要执行的部分,可以用 -e 选项来突出显示(但这不是必须的):

$ awk -F, -e '{print $2;}' colours.txtyellowbluegreen[...]

记录和字段

awk 将输入数据视为一系列记录,通常是按行分割的。换句话说,awk 将文本中的每一行视作一个记录。每一记录包含多个字段。一个字段由字段分隔符分隔开来,字段是记录的一部分。

默认情况下,awk 将各种空白符,如空格、制表符、换行符等视为分隔符。值得注意的是,在 awk 中,多个空格将被视为一个分隔符。所以下面这行文本有两个字段:

raspberry red

这行也是:

tuxedo                  black

其他分隔符,在程序中不是这么处理的。假设字段分隔符是逗号,如下所示的记录,就有三个字段。其中一个字段可能会是 0 个字节(假设这一字段中不包含隐藏字符)

a,,b

awk 程序

awk 命令的程序部分是由一系列规则组成的。通常来说,程序中每个规则占一行(尽管这不是必须的)。每个规则由一个模式,或一个或多个动作组成:

模式 { 动作 }

在一个规则中,你可以通过定义模式,来确定动作是否会在记录中执行。模式可以是简单的比较条件、正则表达式,甚至两者结合等等。

这个例子中,程序只会显示包含单词 “raspberry” 的记录:

$ awk '/raspberry/ { print $0 }' colours.txtraspberry red 99

如果没有文本符合模式,该动作将会应用到所有记录上。

并且,在一条规则只包含模式时,相当于对整个记录执行 { print },全部打印出来。

Awk 程序本质上是数据驱动的,命令执行结果取决于数据。所以,与其他编程语言中的程序相比,它还是有些区别的。

NF 变量

每个字段都有指定变量,但针对字段和记录,也存在一些特殊变量。NF 变量,能存储 awk 在当前记录中找到的字段数量。其内容可在屏幕上显示,也可用于测试。下面例子中的数据,来自上篇文章文本:

$ awk '{ print $0 " (" NF ")" }' colours.txtname       color  amount (3)apple      red    4 (3)banana     yellow 6 (3)[...]

awk 的 print 函数会接受一系列参数(可以是变量或者字符串),并将它们拼接起来。这就是为什么在这个例子里,每行结尾处,awk 会以一个被括号括起来的整数表示字段数量。

NR 变量

另外,除了统计每个记录中的字段数,awk 也统计输入记录数。记录数被存储在变量 NR 中,它的使用方法和其他变量没有任何区别。例如,为了在每一行开头显示行号:

$ awk '{ print NR ": " $0 }' colours.txt1: name       color  amount2: apple      red    43: banana     yellow 64: raspberry  red    35: grape      purple 10[...]

注意,写这个命令时可以不在 print 后的多个参数间添加空格,尽管这样会降低可读性:

$ awk '{print NR": "$0}' colours.txt

printf() 函数

为了让输出结果时格式更灵活,你可以使用 awk 的 printf() 函数。它与 C、Lua、Bash 和其他语言中的 printf 相类似。它也接受以逗号分隔的格式参数。参数列表需要写在括号里。

$ printf 格式, 项目1, 项目2, ...

格式这一参数(也叫格式符)定义了其他参数如何显示。这一功能是用格式修饰符实现的。%s 输出字符,%d 输出十进制数字。下面的 printf 语句,会在括号内显示字段数量:

$ awk 'printf "%s (%d)\n",$0,NF}' colours.txtname       color  amount (3)raspberry  red    4 (3)banana     yellow 6 (3)[...]

在这个例子里,%s (%d) 确定了每一行的输出格式,$0,NF 定义了插入 %s 和 %d 位置的数据。注意,和 print 函数不同,在没有明确指令时,输出不会转到下一行。出现转义字符 \n 时才会换行。

Awk 脚本编程

这篇文章中出现的所有 awk 代码,都在 Bash 终端中执行过。面对更复杂的程序,将命令放在文件(脚本)中会更容易。-f FILE 选项(不要和 -F 弄混了,那个选项用于字段分隔符),可用于指明包含可执行程序的文件。

举个例子,下面是一个简单的 awk 脚本。创建一个名为 example1.awk 的文件,包含以下内容:

/^a/ {print "A: " $0}/^b/ {print "B: " $0}

如果一个文件包含 awk 程序,那么在给文件命名时,最好写上 .awk 的扩展名。这样命名不是强制的,但这么做,会给文件管理器、编辑器(和你)一个关于文件内容的很有用的提示。

执行这一脚本:

$ awk -f example1.awk colours.txtA: raspberry  red    4B: banana     yellow 6A: apple      green  8

一个包含 awk 命令的文件,在最开头一行加上释伴 #!,就能变成可执行脚本。创建一个名为 example2.awk 的文件,包含以下内容:

#!/usr/bin/awk -f## 除了第一行,在其他行前显示行号#NR > 1 { printf "%d: %s\n",NR,$0}

可以说,脚本中只有一行,大多数情况下没什么用。但在某些情况下,执行一个脚本,比记住,然后打一条命令要容易的多。一个脚本文件,也提供了一个记录命令具体作用的好机会。以 # 号开头的行是注释,awk 会忽略它们。

给文件可执行权限:

$ chmod u+x example2.awk

执行脚本:

$ ./example2.awk colours.txt2: apple      red    42: banana     yellow 64: raspberry red    35: grape      purple 10[...]

将 awk 命令放在脚本文件中,有一个好处就是,修改和格式化输出会更容易。在终端中,如果能用一行执行多条 awk 命令,那么输入多行,才能达到同样效果,就显得有些多余了。

试一试

你现在已经足够了解,awk 是如何执行指令的了。现在你应该能编写复杂的 awk 程序了。试着编写一个 awk 脚本,它需要: 至少包括一个条件模式,以及多个规则。如果你想使用除 print 和 printf 以外的函数,可以参考在线 gawk 手册。

下面这个例子是个很好的切入点:

#!/usr/bin/awk -f## 显示所有记录 除了出现以下情况# 如果第一个记录 包含 “raspberry”# 将 “red” 替换成 “pi”$1 == "raspberry" {        gsub(/red/,"pi")}{ print }

试着执行这个脚本,看看输出是什么。接下来就看你自己的了。

这一系列的下一篇文章,将会介绍更多,能在更复杂(更有用!) 脚本中使用的函数。

这篇文章改编自 Hacker Public Radio 系列,一个技术社区博客。


via: https://opensource.com/article/19/11/fields-records-variables-awk

作者:Seth Kenlon 选题:lujun9972 译者:wenwensnow 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

?:还在看吗?

awk 分隔符_awk 中的字段、记录和变量 | Linux 中国相关推荐

  1. Linux下dislocate命令用法,在 Linux 中遨游手册页的海洋 | Linux 中国

    原标题:在 Linux 中遨游手册页的海洋 | Linux 中国 Linux 系统上的手册页可以做的不仅仅是提供特定命令的信息.它们可以帮助你发现你没有意识到的命令. https://linux.cn ...

  2. awk 分隔符_awk命令使用实例

    Awk是为高级文本处理而设计的通用脚本语言.它主要用作报告和分析工具.本文介绍awk在命令行中操作文本的使用方式.脚本Awk是为高级文本处理而设计的通用脚本语言.它主要用作报告和分析工具.本文介绍aw ...

  3. postgresql存图片字段类型_PostgreSQL 入门 | Linux 中国

    安装.设置.创建和开始使用 PostgreSQL 数据库.-- Greg Pittman 每个人或许都有需要在数据库中保存的东西.即使你执着于使用纸质文件或电子文件,它们也会变得很麻烦.纸质文档可能会 ...

  4. java list 去重 相同的相加_Java 中的数据流和函数式编程 | Linux 中国

    学习如何使用 Java 8 中的流 API 和函数式编程结构.-- Marty Kalin 当 Java SE 8(又名核心 Java 8)在 2014 年被推出时,它引入了一些更改,从根本上影响了用 ...

  5. 没有dpkg命令_ffsend:在命令行中通过 FireFox Send 分享文件 | Linux 中国

    在过去我们已经写了多篇有关安全分享这个话题的文章,今天我们甚至还将继续讨论这个话题,我们将介绍名为 ffsend 的工具.-- Vinoth Kumar Linux 用户偏爱使用 scp 或 rsyn ...

  6. ubuntu修改ip地址后如何保存_如何在 Ubuntu 中检查你的 IP 地址 | Linux 中国

    不知道你的 IP 地址是什么?以下是在 Ubuntu 和其他 Linux 发行版中检查 IP 地址的几种方法.-- Sergiu 不知道你的 IP 地址是什么?以下是在 Ubuntu 和其他 Linu ...

  7. 使用变量_在 Linux 中使用变量 | Linux 中国

    让我们来看看所有这些 $ 值可以告诉你什么.-- Sandra Henry-stocker 变量通常看起来像 $var 这样,但它们也有 $1.$*.$? 和 $$ 这种形式.让我们来看看所有这些 $ ...

  8. linux 在命令行中复制的快捷键_在 Linux 中加速工作的键盘快捷键 | Linux 中国

    学习键盘快捷键将使生产率提高 3.3%-- S Sathyanarayanan 操作鼠标.键盘和菜单会占用我们很多时间,这些可以使用键盘快捷键来节省时间.这不仅节省时间,还可以使用户更高效. 你是否意 ...

  9. Linux中的 awk查找日志中的相关记录

    假设要在 api.log.201707201830 文件中,(此文件的多个字段数据以不可见字符^A(键盘上按下Ctrl+V+A)分隔),要输出第70个字段: awk -F '^A' '{print $ ...

最新文章

  1. 【排序】插入类排序—(折半)插入排序、希尔排序
  2. Vue (二) --- Vue对象提供的属性功能
  3. 判断字符串是否为空--string.Empty、string=、s.length==0
  4. 获取数据库时间相差8小时_JAVA 程序展示时间与数据表保存的时间相差了13个小时...
  5. Python中使用xpath获取select option的每一行的text和value
  6. os.path.basename()
  7. mysql grep 提取错误日志_通过grep 获取MySQL错误日志信息的方法
  8. MATLAB中simulink的模糊PID控制
  9. 手机也能实时查看开关门状态?Zigbee 智慧厕所门亮了
  10. 最大公约数与最小公倍数的求法
  11. zabbix纯内网环境监控服务器发送邮件报警
  12. firefoxos中打开app
  13. java计算机毕业设计体育用品购物系统源码+数据库+系统+lw文档+mybatis+运行部署
  14. k8s-linkerd
  15. 基于jupyter notebook的简单爬虫学习记录
  16. 不止Alexa和AWS,揭秘亚马逊人工智能发展史
  17. 恐惧贪婪指数(Fear Greed Index)
  18. 转载--文章(感谢陈晨博主分享) 关于 Json.net
  19. python处理Jenkins Job配置文件config.xml
  20. 量产技术-把kingston U盘做成USB-CDROM启动盘

热门文章

  1. jittor和pytorch生成网络对比之cgan
  2. redis安装教程 windows环境
  3. JS学习系列08 - 内存分配
  4. spring mvc dubbo ios android整合cms内容发布平台
  5. Angular vs React 最全面深入对比
  6. ognl 表达式常用表达式语言
  7. Automate repeatedly actions in work
  8. 面试必备杀技:SQL查询专项训练!
  9. java实现俄罗斯方块游戏
  10. 参考基因组中的特殊序列