轨道
/
AWK
AWK
/
练习
/
基础
基础

基础

学习练习

简介

基础

我们把**语言称为AWK**,把负责解释 AWK 程序的**可执行文件称为awk或gawk**。

模式与动作

一个 AWK 程序由模式-动作对组成

pattern1 { action1 }
pattern2 { action2 }
...

模式可以是用来匹配输入的正则表达式模式。 它也可以是任何结果为 true/false 值的表达式。

动作是一条或多条 AWK 命令。 包裹它的大括号不能省略。

如果模式的结果为 true,就会执行对应的动作。

记录与字段

AWK 会把输入解析成一系列记录。 每条记录都会被拆分成零个或多个字段。

默认行为是:

  • 用换行符作为“记录分隔符”把输入拆分成记录,所以每一行就是一条记录。
  • 用空白字符作为“字段分隔符”把记录拆分成字段,所以每一个词就是一个字段。

模式与动作(续)

模式可以省略,此时动作会针对每一条输入记录执行。

动作也可以省略,此时默认动作是打印当前记录。

特殊模式

有两个经常用到的特殊模式。

  • BEGIN会在读取任何输入之前执行对应的动作。
  • END会在所有输入读取完毕之后执行对应的动作。

字段变量

可以用$1、$2、$3等来引用字段。

当前记录是$0。

下面是其他一些常用的内置变量。

控制输入解析的内置变量
  • RS是输入记录分隔符。 如前所述,它的默认值是换行符。
  • FS是输入字段分隔符。

这些变量通常会在BEGIN动作块中设置。

传递信息的内置变量

这些变量由 AWK 在程序执行期间自动设置。

  • NF保存当前记录中字段的数量。
    • 想获取最后一个字段的值,可以使用$NF。
  • NR保存当前的记录编号。
    • 处理多个输入文件时,NR保存的是到目前为止已处理记录的总数。
  • FNR保存当前输入文件中的当前记录编号。
    • 为了说明 NR 与 FNR 的区别,下面是一个常见的 AWK 惯用法。
      NR == FNR {action}
      
      它的意思是“累计记录编号等于当前文件的记录编号”。 只有第一个输入文件中的记录才可能满足这个条件。

真值性

AWK 使用与 C 相同的真值性概念。

  • 数字0为 false。
  • 其他任何数字都为 true。

由于 AWK 是一门文本处理语言,真值也扩展到了字符串。

  • 空字符串""为 false。
  • 任何非空字符串都为 true。

注释

注释以#字符开头,一直延伸到行尾。

示例

在类 Unix 系统上,/etc/passwd包含用户的信息。 每个用户单独占一行,字段之间用冒号分隔。

要列出用户名:

awk '
    BEGIN { FS = ":" }
    { print $1 }
' /etc/passwd

注意{print $1}这个动作没有模式,所以它会对每一条记录执行。

如果我们想把输出限制为只用 bash 作为登录 shell 的用户,可以这样做:

awk '
    BEGIN { FS = ":" }
    $7 == "/bin/bash" { print $1 }
' /etc/passwd

说明

从前,有一座繁华的城市,名叫 Cyberspace。 Cyberspace 是一座数字大都市,每天都有数百万居民登录和退出。 为了记录所有这些用户,Cyberspace 有一个特殊的文件,叫作 /etc/passwd。

/etc/passwd 文件就像这座城市的电话簿。 它列出了系统上所有拥有账号的用户,以及每位用户的一些重要信息:

n 字段
1 用户名
2 密码("x" 表示出于安全考虑,真正的密码存放在别处)
3 UID,一个唯一的数字用户 ID
4 GID,一个唯一的数字组 ID(通常与 UID 相同)
5 用户信息(通常是用户的全名,但也可以包含其他信息)
6 主目录
7 登录 shell

各字段之间用冒号分隔。 下面是一个典型的条目:

glennj:x:1010:1010:Glenn Jackman:/home/glennj:/usr/local/bin/fish

这个文件由一个系统管理员团队管理,他们负责创建新账号、更新已有账号以及删除旧账号。 系统管理员是 Cyberspace 的守门人,确保只有经过授权的用户才能访问系统。

有一天,团队新招了一位叫 Alex 的系统管理员。 Alex 很高兴能接下这份工作,很快就摸清了 /etc/passwd 文件的门道。 他们学会了如何向系统添加新用户、如何更新用户信息,以及如何删除旧用户。

在处理 /etc/passwd 文件的过程中,Alex 注意到了一些奇怪的地方。 有些用户的主目录很奇怪,很不寻常。 有些用户的主目录被设成了 /dev/null,还有一些用户的主目录被设成了根本不存在、莫名其妙的路径。

Alex 意识到,这些用户并不是真人,而是黑客创建的虚假账号。 黑客找到了一种利用系统漏洞的方法,创建这些虚假账号来入侵 Cyberspace。

Alex 知道自己必须采取行动。 他们用 awk 分析 /etc/passwd 文件,并写了一个脚本来找出所有虚假账号。 然后他们和团队其他成员一起删除了这些账号,并修补了让黑客得以创建这些账号的漏洞。

多亏 Alex 用上了 awk,团队才得以找出并删除这些虚假账号,让 Cyberspace 对每个人都更安全。 系统管理员继续管理着 /etc/passwd 文件,让它保持最新、安全,并确保只有经过授权的用户才能访问系统。

现在,轮到你来做一名像 Alex 一样的系统管理员了。

Note

下面是解这道练习时还需要用到的一些 AWK 语法。

  • 布尔运算符和其他语言类似:

    运算 示例
    与 expr1 && expr2
    或 expr1 || expr2
    非 ! expr
  • 调用函数的语法你一定很熟悉:

    function greet(name) {
        print "Hello", name
    }
    BEGIN {
        greet("Mary")   # prints "Hello Mary"
    }
    

1. 列出用户名

写一个 awk 程序,打印 passwd 文件中每一行里以冒号分隔的第一个字段。

2. 打印行号

写一条 awk 命令,打印输入文件中每条记录的行号。 只打印行号,不要打印其他任何信息。

3. 打印主目录无效的记录。

在 Cyberspace 中,“有效”的主目录以 /home 或 /root 开头。 打印输入文件中主目录无效的记录。

4. 打印使用 bash 的有效用户

打印主目录有效并且登录 shell 是 bash 的记录。


来源

ChatGPT 对话
通过 GitHub 编辑 链接将在新窗口或新标签页中打开
AWK Exercism

准备好开始 基础 了吗?

注册 Exercism,借助 3 个概念92 个练习 和真人导师指导,学习并掌握 AWK,全部免费。