AWK 编程范型 脚本 きゃくほん 、过程式 しき 、数 かず 据 すえ 驱动[ 1] [ 2] 設計 せっけい 者 しゃ 阿 おもね 尔佛雷 かみなり 德 とく ·艾 もぐさ 侯 こう 、彼 かれ 得 とく ·溫 ぬる 伯 はく 格 かく 以及布 ぬの 萊恩·柯林漢 かん 发行时间 1977年 ねん 当 とう 前 ぜん 版本 はんぽん 型 かた 態 たい 系統 けいとう 无;支持 しじ 字 じ 符 ふ 串 くし ,整数 せいすう 和 わ 浮点数 すう ,以及正 せい 则表达式 操作 そうさ 系 けい 统跨 またが 平台 ひらだい 網 あみ 站cm.bell-labs.com/cm/cs/awkbook/index.html awk, GNU Awk, mawk, nawk, MKS AWK, Thompson AWK(编译器 き ), Awka(编译器 き ) old awk oawk 1977, new awk nawk 1985, GNU Awk gawkC , Sed , SNOBOL [ 1] [ 2] Tcl , AMPL , Perl
AWK 是 ぜ 一 いち 种优良 りょう 的 てき 文 ぶん 本 ほん 处理工具 こうぐ ,Linux 及Unix 环境中 ちゅう 现有的 てき 功 こう 能 のう 最强 さいきょう 大 だい 的 てき 数 かず 据 すえ 处理 引擎之 の 一 いち 。这种编程及数据 すえ 操作 そうさ 语言(其名称 たたえ 得 え 自 じ 于它的 てき 创始人 じん 阿 おもね 尔佛雷 かみなり 德 とく ·艾 もぐさ 侯 こう 、彼 かれ 得 とく ·溫 ぬる 伯 はく 格 かく 和 わ 布 ぬの 萊恩·柯林漢 かん 姓氏 せいし 的 てき 首 くび 个字母 はは )的 てき 最大 さいだい 功 こう 能取 のとろ 决于一个人所拥有的知识。AWK提供 ていきょう 了 りょう 极其强大 きょうだい 的 てき 功 こう 能 のう :可 か 以进行正 ゆきまさ 则表达式的 てき 匹 ひき 配 はい ,样式装 そう 入 いれ 、流 ながれ 控 ひかえ 制 せい 、数学 すうがく 运算符 ふ 、进程控 ひかえ 制 せい 语句甚至于内置 おけ 的 てき 变量和 わ 函数 かんすう 。它具备了一个完整的语言所应具有的几乎所有精美特性。实际上 じょう AWK的 てき 确拥有 ゆう 自己 じこ 的 てき 语言:AWK程 ほど 序 じょ 设计语言 ,三位创建者已将它正式定义为“样式扫描和 わ 处理语言”。它允许创建 けん 简短的 てき 程 ほど 序 じょ ,这些程 ほど 序 じょ 读取输入文 ぶん 件 けん 、为数据 すえ 排 はい 序 じょ 、处理数 すう 据 すえ 、对输入 にゅう 执行计算以及生成 せいせい 报表,还有无数其他的 てき 功 こう 能 のう 。gawk是 ぜ AWK的 てき GNU版本 はんぽん 。
最 さい 简单地 ち 说,AWK是 ぜ 一种用于处理文本的编程语言工具。AWK在 ざい 很多方面 ほうめん 类似于Unix shell 编程语言,尽 つき 管 かん AWK具有 ぐゆう 完全 かんぜん 属 ぞく 于其本身 ほんみ 的 てき 语法。它的设计思想 しそう 来 らい 源 げん 于SNOBOL4 、sed 、Marc Rochkind设计的 てき 有效 ゆうこう 性 せい 语言、语言工具 こうぐ yacc 和 わ lex ,当然 とうぜん 还从C语言 中 ちゅう 获取了 りょう 一 いち 些优秀 しゅう 的 てき 思想 しそう 。在 ざい 最初 さいしょ 创造AWK时,其目的 もくてき 是 ぜ 用 よう 于文本 ほん 处理,并且这种语言的 てき 基 もと 础是,只 ただ 要 よう 在 ざい 输入数 すう 据 すえ 中有 ちゅうう 模 も 式 しき 匹 ひき 配 はい ,就执行 ぎょう 一 いち 系列 けいれつ 指令 しれい 。该实用 よう 工具 こうぐ 扫描文 ぶん 件 けん 中 ちゅう 的 てき 每 ごと 一 いち 行 ぎょう ,查找与命令 めいれい 行 ぎょう 中 ちゅう 所 しょ 给定内容 ないよう 相 しょう 匹 ひき 配 はい 的 てき 模 も 式 しき 。如果发现匹 ひき 配 はい 内容 ないよう ,则进行 ぎょう 下 か 一个编程步骤。如果找不到 いた 匹 ひき 配 はい 内容 ないよう ,则继续处理 り 下 か 一 いち 行 ぎょう 。
AWK是 ぜ 一种处理文本文件的语言。它将文 ぶん 件 けん 作 さく 为记录序列 じょれつ 处理。在 ざい 一般 いっぱん 情 じょう 况下,文 ぶん 件 けん 内容 ないよう 的 てき 每 ごと 行 あるき 都 と 是 ぜ 一 いち 个记录。每 まい 行内 こうない 容 よう 都会 とかい 被 ひ 分割 ぶんかつ 成 なり 一 いち 系列 けいれつ 的 てき 域 いき ,因 いん 此,我 わが 们可以认为一行的第一个词为第一个域,第 だい 二个词为第二个,以此类推。AWK程 ほど 序 じょ 是 ぜ 由 よし 一些处理特定模式的语句块构成的。AWK一次可以读取一个输入行。对每个输入行 にゅうこう ,AWK解 かい 释器会 かい 判断 はんだん 它是否 ひ 符合 ふごう 程 ほど 序 ついで 中出 なかいで 现的各 かく 个模式 しき ,并执行 ぎょう 符合 ふごう 的 てき 模 も 式 しき 所 しょ 对应的 てき 动作。
AWK程 ほど 序 じょ 是 ぜ 由 よし 一 いち 系列 けいれつ 模 も 式 しき --动作对组成 なり 的 てき ,写 うつし 做
pattern { action }
其中pattern
表示 ひょうじ AWK在 ざい 数 すう 据 すえ 中 ちゅう 查找的 てき 内容 ないよう ,而action
是 ぜ 在 ざい 找到匹 ひき 配 はい 内容 ないよう 时所执行的 てき 一 いち 系列 けいれつ 命令 めいれい 。输入行 にゅうこう 被 ひ 分 ぶん 成 なり 了 りょう 一 いち 些记录:记录默认由换行符 ふ 分割 ぶんかつ ,因 いん 此输入会 にゅうかい 按照行 ぎょう 进行分割 ぶんかつ 。程 ほど 序 じょ 使用 しよう 给定的 てき 条件 じょうけん 一个个的测试每条记录,并执行 ぎょう 测试通 どおり 过的条件 じょうけん 所 しょ 对应的 てき action
。pattern
和 わ action
都 と 可 か 以省略 しょうりゃく 不 ふ 写 うつし 。无pattern
默 だま 认匹配 はい 全部 ぜんぶ 的 てき 记录;而无action
则是打 だ 印 しるし 原始 げんし 记录。简单的 てき AWK表 ひょう 达式之 の 外 そと ,pattern
可 か 以是BEGIN
或 ある END
;这两种条件 じょうけん 对应的 てき action
分 ぶん 别是读取所有 しょゆう 的 てき 记录之 の 前 ぜん 和之 かずゆき 后 きさき 。同 どう 时,如pattern1, pattern2
的 てき 条件 じょうけん 表示 ひょうじ 符合 ふごう 条件 じょうけん pattern1
和 わ pattern2
的 てき 记录及其之 の 间的部分 ぶぶん 。
除 じょ 了 りょう 一般 いっぱん 的 てき ,C语言 风格的 てき 算 さん 术和逻辑运算符 ふ 外 がい ,AWK允 まこと 许运算 さん 符 ふ ~ ,用 もちい 来 らい 测试正 せい 则表达式是 ぜ 否 いや 可 か 以与一字符串匹配。作 さく 为语法糖 とう ,没 ぼつ 有 ゆう ~ 运算符 ふ 的 てき 正 せい 则表达式会 かい 被 ひ 用 もちい 来 らい 对当前 ぜん 记录进行测试,相当 そうとう 于/regexp/ ~ $0
。
AWK命令 めいれい 即 そく 为前文例 ぶんれい 子中 こなか 以action 指 ゆび 代 だい 的 てき 语句。AWK命令 めいれい 可 か 以包括 ほうかつ 函数 かんすう 调用,变量赋值,计算,及/或 ある 各 かく 项的组合。标准AWK提供 ていきょう 了 りょう 许多内 ない 建 けん 函数 かんすう ;其部分 ぶぶん 实现则可能 かのう 提供 ていきょう 了 りょう 更 さら 多 た 的 てき 内 ない 建 けん 函数 かんすう 。同 どう 时,AWK的 てき 部分 ぶぶん 实现支持 しじ 动态链接库 ,使 つかい 得 とく 其可以支持 しじ 更 さら 多 た 的 てき 函数 かんすう 。
便利 べんり 起 おこり 见,下 しも 述 じゅつ 例 れい 子中 こなか 可能 かのう 省略 しょうりゃく 大 だい 括 くく 号 ごう ({ } )。
print 命令 めいれい 用 よう 于输出 で 文 ぶん 本 ほん 。其输出 で 的 てき 文 ぶん 本 ほん 总是以"输出记录分 ぶん 隔 へだた 符 ふ "(Output record separator, ORS)分割 ぶんかつ 的 てき ,其默认值为换行 ぎょう 符 ふ 。该命令 めいれい 的 てき 最 さい 简形式 しき 为:
print
会 かい 输出当 とう 前 ぜん 记录的 てき 内容 ないよう 。在 ざい AWK中 ちゅう ,记录会 かい 被 ひ 分割 ぶんかつ 成 なり “域 いき ”,它们可 か 以被分 ぶん 别显示 しめせ 或 ある 使用 しよう :
print $1
显示当 とう 前 ぜん 记录的 てき 第 だい 1个域
print $1, $3
显示当 とう 前 ぜん 记录的 てき 第 だい 1和 わ 第 だい 3个域,并以预定义的输出域 いき 分 ぶん 隔 へだた 符 ふ (Output field separator, OFS)分 ぶん 隔 へだた ,其默认值为一个空格 かく 符 ふ
虽然域 いき 的 てき 符号 ふごう ($X )可能 かのう 类似于某些语言 ごと 中 ちゅう 的 てき 变量(例 れい 如PHP 和 わ perl ),但 ただし 在 ざい AWK中 ちゅう ,它们指 ゆび 代 だい 的 てき 是 ぜ 当 とう 前 ぜん 记录的 てき 域 いき 。另外,$0 是 ぜ 指 ゆび 整 せい 个记录。事 こと 实上,命令 めいれい print
和 わ print $0
的 てき 效果 こうか 是 ぜ 相 しょう 同 どう 的 てき 。
print 命令 めいれい 也可以显示 しめせ 变量、计算、函数 かんすう 调用的 てき 结果:
print 3+2
print foobar(3)
print foobar(variable)
print sin(3-2)
其输出 で 可 か 以重定 てい 向 こう 到 いた File:
print "expression" > "file name"
或 ある 重定 しげさだ 向 こう 到 いた 管 かん 道 どう :
print "expression" | "command"
AWK的 てき 内 ない 建 けん 变量包括 ほうかつ 域 いき 变量,例 れい 如$1, $2, $3,以及$0。这些变量给出了 りょう 记录中 ちゅう 域 いき 的 てき 内容 ないよう 。
内 うち 建 けん 变量也包括 ほうかつ 一 いち 些其他 た 变量:
NR:已 やめ 输入记录的 てき 条 じょう 数 すう 。
NF:当 とう 前 ぜん 记录中 ちゅう 域 いき 的 てき 个数。记录中 ちゅう 最 さい 后 きさき 一 いち 个域可 か 以以$NF
的 てき 方式 ほうしき 引用 いんよう 。
FILENAME:当 とう 前 ぜん 输入文 ぶん 件 けん 的 てき 文 ぶん 件名 けんめい 。
FS:“域 いき 分 ぶん 隔 へだた 符 ふ ”,用 よう 于将输入记录分割 ぶんかつ 成 なり 域 いき 。其默认值为“空白 くうはく 字 じ 符 ふ ”,即 そく 空 そら 格和 かくわ 制 せい 表 ひょう 符 ふ 。FS可 か 以替换为其它字 じ 符 ふ ,从而改 あらため 变域分 ぶん 隔 へだた 符 ふ 。
RS:当 とう 前 まえ 的 てき “记录分 ぶん 隔 へだた 符 ふ ”。默 だま 认状态下,输入的 てき 每 ごと 行 あるき 都 と 被 ひ 作 さく 为一个记录,因 いん 此默认记录分隔 へだた 符 ふ 是 ぜ 换行符 ふ 。
OFS:“输出域 いき 分 ぶん 隔 へだた 符 ふ ”,即 そく 分 ぶん 隔 へだた print
命令 めいれい 的 てき 参 まいり 数 すう 的 てき 符号 ふごう 。其默认值为空格 かく 。
ORS:“输出记录分 ぶん 隔 へだた 符 ふ ”,即 そく 每 まい 个print
命令 めいれい 之 の 间的符号 ふごう 。其默认值为换行 ぎょう 符 ふ 。
OFMT:“输出数字 すうじ 格式 かくしき ”(Format for numeric output),其默认值为"%.6g"。
变量名 めい 可 か 以是语言关键字 じ 外的 がいてき ,只 ただ 包含 ほうがん 大小 だいしょう 写 うつし 拉 ひしげ 丁字 ていじ 母 はは ,数字 すうじ 和 わ 下 か 划线(“_”)的 てき 任意 にんい 字 じ 。而操作 そうさ 符 ふ “+ - * /”则分别代表 だいひょう 加 か ,减,乘 じょう ,除 じょ 。简单的 てき 将 はた 两个变量(或 ある 字 じ 符 ふ 串 くし 常 つね 量 りょう )放 ひ 在 ざい 一起 かずき ,则会将 しょう 二 に 者 しゃ 串 くし 接 せっ 为一个字符 ふ 串 くし 。若 わか 二者间至少有一个是常量,则中间可以不加 か 空 そら 格 かく ;但 ただし 若 わか 二 に 者 しゃ 均 ひとし 为变量 りょう ,中 ちゅう 间必须包括 ほうかつ 空 そら 格 かく 。字 じ 符 ふ 串 くし 常 つね 量 りょう 是 ぜ 以双引号(“"”)分 ぶん 隔 へだた 的 てき 。语句无需以分号 ごう 结尾。另外,注 ちゅう 释是以“#”开头的 てき 。
函数 かんすう 是 ぜ 以与C语言类似的 てき 方式 ほうしき 定 てい 义的,以关键字function
开头,后 きさき 面 めん 跟函数 すう 名称 めいしょう ,参 まいり 数列 すうれつ 表 ひょう 和 わ 函数 かんすう 体 たい 。
# 示 しめせ 例 れい 函数 かんすう
function add_three (number) {
return number + 3
}
上面 うわつら 的 てき 函数 かんすう 可 か 以如此调用 よう :
print add_three(36) # 输出39
函数 かんすう 可 か 以拥有 ゆう 其私有 しゆう 变量。其私有 しゆう 变量可 か 以写在 ざい 参 さん 数列 すうれつ 表 ひょう 之 の 后 きさき ,因 いん 为这些值会 かい 在 ざい 调用函数 かんすう 时被忽 ゆるがせ 略 りゃく 。通常 つうじょう 可 か 以在参 さん 数列 すうれつ 表 ひょう 中 ちゅう 参 さん 数 すう 和 わ 私有 しゆう 变量之 の 间加入 かにゅう 一 いち 些空格 かく ,用 よう 以区别“真正 しんせい 的 てき ”参 さん 数 すう 和 わ 私有 しゆう 变量。
函数 かんすう 声明 せいめい 中 ちゅう ,函数 かんすう 名和 なわ 括 くく 号 ごう 间可以有任意 にんい 空 そら 格 かく ,但 ただし 在 ざい 调用时二者 しゃ 必须紧邻。
AWK的 てき hello world 程 ほど 序 じょ 为:
BEGIN { print "Hello, world!" }
注意 ちゅうい 此处无需写 うつし 出 で exit
语句,因 いん 为唯一 いち 的 てき 模 も 式 しき 是 ぜ BEGIN
。
输出长度大 だい 于80字 じ 符 ふ 的 てき 行 ぎょう 。注意 ちゅうい 模 も 式 しき 的 てき 默 だま 认行为是输出当 とう 前 まえ 行 ぎょう 。
length($0) > 80
对输入 いれ 中 ちゅう 的 てき 单词进行计数,然 しか 后 きさき 输出行 ぎょう 数 すう ,单词数 すう 和字 わじ 符 ふ 数 すう (类似wc )。
{
w += NF
c += length + 1
}
END { print NR, w, c }
由 よし 于没有 ゆう 提供 ていきょう 模 も 式 しき ,输入的 てき 全部 ぜんぶ 行 あるき 都 と 可 か 以匹配 はい 该模式 しき ,因 いん 此对每 ごと 行 ぎょう 都会 とかい 执行预定操作 そうさ 。注意 ちゅうい w+=NF
的 てき 含义等 とう 同 どう 于w = w + NF
。
{ s += $NF }
END { print s + 0 }
s
是 ぜ 数 すう 值$NF
的 てき 累加 るいか ,$NF
是 ぜ 每 ごと 条 じょう 记录中 ちゅう 的 てき 最 さい 后 きさき 一 いち 个域,NF
(没 ぼつ 有 ゆう $)是 ぜ 当 とう 前 まえ 行 ぎょう 中 ちゅう 域 いき 的 てき 数量 すうりょう 。例 れい 如一个域数为4的 てき 行 ぎょう 中 ちゅう $NF
相当 そうとう 于$4
。事 こと 实上,$
是 ぜ 一 いち 个具有 ぐゆう 最高 さいこう 优先级 的 てき 一元 いちげん 运算符 ふ 。(若 わか 一 いち 行 ぎょう 没 ぼつ 有 ゆう 域 いき ,则有NF
为0,而$NF
相当 そうとう 于$0
,是 ぜ 整 せい 行 ぎょう ,在 ざい 这种情 じょう 况下,要 よう 么是空 そら 串 くし ,要 よう 么只有 ゆう 空白 くうはく 符 ふ ,因 いん 此其数 すう 值为0。)
文 ぶん 件 けん 结束时,END
模 も 式 しき 得 え 到 いた 了 りょう 匹 ひき 配 はい ,因 いん 此可以输出 で s
。然 しか 而,在 ざい 没 ぼつ 有 ゆう 输入行 にゅうこう 的 てき 情 じょう 况下,s
会 かい 没 ぼつ 有 ゆう 值,从而导致没 ぼつ 有 ゆう 输出。因 よし 此,对其加 か 0可 か 以使AWK在 ざい 这种情 じょう 况下对其赋值,从而得 え 到 いた 一 いち 个数值。这种方法 ほうほう 是 ぜ 将 はた 字 じ 符 ふ 串 くし 强制 きょうせい 转化为数值的惯用法 ほう (反 はん 之 これ ,与 あずか 空 むなし 串 くし 连接则是将 しょう 数 すう 值强制 きょうせい 转换为字符 ふ 串 くし 的 てき 方法 ほうほう ,例 れい 如s ""
)。如此处理之 の 后 きさき ,若 わか 程 ほど 序 じょ 输入为空文 くうぶん 件 けん ,可 か 以得到 いた “0”作 さく 为输出 で ,而不是 ぜ 一 いち 个空行 くうぎょう 。
匹 ひき 配 はい 输入行 にゅうこう 中 ちゅう 的 てき 范围[ 编辑 ]
$ yes Wikipedia | awk 'NR % 4 == 1, NR % 4 == 3 { printf "%6d %s\n", NR, $0 }' | sed 7q
1 Wikipedia
2 Wikipedia
3 Wikipedia
5 Wikipedia
6 Wikipedia
7 Wikipedia
9 Wikipedia
$
yes 命令 めいれい 重 じゅう 复输入 にゅう 其参数 すう (默 だま 认则是 ぜ 输出“y”)。在 ざい 这里,我 わが 们让该命令 めいれい 输出“Wikipedia”。动作块则输出带行号 ごう 的 てき 内容 ないよう 。printf
函数 かんすう 可 か 以模拟标准 じゅん C中 なか 的 てき printf
函数 かんすう ,其效果 こうか 与 あずか 前述 ぜんじゅつ 的 てき print
函数 かんすう 类似。而符合 ふごう 模 も 式 しき 的 てき 行 ぎょう 是 ぜ 这样产生的 てき :NR
是 ぜ 记录的 てき 编号,也就是 ぜ AWK正 ただし 在 ざい 处理行 ぎょう 的 てき 行 ぎょう 号 ごう (从1开始)。“%”是 これ 取 と 余 よ 数 すう 操作 そうさ 符 ふ 。因 よし 此,NR % 4 == 1
对第1,5,9等 とう 行 ぎょう 为真。类似的 てき ,NR % 4 == 3
对3,7,11等 とう 行 ぎょう 为真。范围模 も 式 しき 在 ざい 其第一 いち 部分 ぶぶん 匹 ひき 配 はい (例 れい 如对第 だい 1行 ぎょう )之 の 前 ぜん 为假,并在第 だい 二 に 部分 ぶぶん 匹 ひき 配 はい (例 れい 如第3行 ぎょう )之 の 前 ぜん 为真。然 しか 后 きさき ,再 さい 在 ざい 第 だい 二次匹配上其第一部分(例 れい 如第5行 ぎょう )前 ぜん 为假。sed
命令 めいれい 则是用 よう 于截取其前7行 ぎょう 输出,防止 ぼうし yes
命令 めいれい 一直运行下去。若 わか head
命令 めいれい 可用 かよう 的 てき 话,这行命令 めいれい 的 てき 效果 こうか 和 わ head -n7
相 あい 同 どう 。
若 わか 范围模 も 式 しき 的 てき 第 だい 一部分永远为真,例 れい 如设定 てい 为“1”,可 か 以用来 らい 使 つかい 该范围从输入的 てき 最 さい 开始开始。类似的 てき ,若 わか 第 だい 二部分总是为假,例 れい 如“0”,则该范围的 てき 结束即 そく 为输入 いれ 的 てき 结束。
命令 めいれい
/^--cut here--$/, 0
会 かい 输出从符合 ふごう 正 せい 则表达式“^--cut here--$”开始的 てき 输入行 にゅうこう ,也即从只包含 ほうがん “--cut here--”的 てき 行 ぎょう 开始,直 ちょく 到 いた 输入的 てき 结束。
使用 しよう 关联数 すう 组 计算词频:
BEGIN {
FS="[^a-zA-Z]+"
}
{
for(i=1; i<=NF; ++i)
words[tolower($i)]++
}
END {
for(i in words)
print i, words[i]
}
BEGIN
块设定 てい 域 いき 分 ぶん 隔 へだた 符 ふ 为任意 にんい 非 ひ 字母 じぼ 字 じ 符 ふ 。值得注意 ちゅうい 的 てき 是 ぜ ,分 ふん 隔 へだた 符 ふ 不 ふ 仅可以是字 じ 符 ふ 串 くし ,也可以是正 ぜせい 则表达式。然 しか 后 きさき ,程 ほど 序 じょ 对每个输入行 にゅうこう 执行相 しょう 同 どう 的 てき 操作 そうさ 。在 ざい 此,对每个域,我 わが 们累加 るいか 其小写 うつし 形式 けいしき 出 で 现的次数 じすう 。最 さい 后 きさき ,在 ざい END
块中,我 わが 们输出 で 单词及其出 で 现的次数 じすう 。代 だい 码
for(i in words)
建立 こんりゅう 了 りょう 一个遍历关联数组中元素的循环,其中,i
会 かい 被 ひ 设为对应的 てき 键。这一点和多数语言不同,而和Objective-C 2.0 中 なか 的 てき for...in
语法相似 そうじ 。这样的 てき 语法允 まこと 许以简单的 てき 方式 ほうしき 遍 へん 历数组,从而输出这些单词。另外,tolower
函数 かんすう 是 ぜ One True awk(见下文 ぶん )的 てき 附加 ふか 函数 かんすう 。
这个程 ほど 序 じょ 可 か 以以多 た 种不同 どう 形式 けいしき 出 で 现。第 だい 一 いち 个使用 しよう Bourne shell 脚 あし 本来 ほんらい 完成 かんせい 大 だい 部分 ぶぶん 工作 こうさく 。这也是 ぜ 最短 さいたん 的 てき 一 いち 个方法 ほう :
$ cat grepinawk
pattern=$1
shift
awk '/'$pattern'/ { print FILENAME ":" $0 }' $*
$
awk命令 めいれい 中 ちゅう 的 てき $pattern
并没有 ゆう 为引号 ごう 所 しょ 保 ほ 护。在 ざい 这里,模 も 式 しき 可 か 以检查输入行 にゅうこう ($0
)是 ぜ 否 いな 与 あずか 之 これ 匹 ひき 配 はい 。FILENAME
变量则包含 ほうがん 了 りょう 当 とう 前 まえ 的 てき 文 ぶん 件名 けんめい 。awk没 ぼつ 有 ゆう 显式的 てき 字 じ 符 ふ 串 くし 连接操作 そうさ 符 ふ ;与 あずか BASH 相似 そうじ ,只 ただ 需简单的将 はた 字 じ 符 ふ 串 くし 并列即 そく 可 か 。$0
则会输出原始 げんし 的 てき 输入行 にゅうこう 。
也有 やゆう 另外的 てき 方法 ほうほう 来 らい 完成 かんせい 同 どう 样的任 にん 务。下面 かめん 的 てき 脚本 きゃくほん 直接 ちょくせつ 在 ざい awk中 ちゅう 访问环境变量 。
$ cat grepinawk
pattern=$1
shift
awk '$0 ~ ENVIRON["pattern"] { print FILENAME ":" $0 }' $*
$
这个脚本 きゃくほん 用 よう 到 いた 了 りょう 数 すう 组ENVIRON
,一 いち 个One True awk中 ちゅう 引入的 てき 量 りょう 。其作用 よう 类似与 あずか POSIX 标准中 ちゅう 的 てき getenv (3) 函数 かんすう 。这个脚本 きゃくほん 先 さき 建立 こんりゅう 了 りょう 一 いち 个名为pattern
的 てき 环境变量,其值为脚本 きゃくほん 的 てき 第 だい 一 いち 个参数 すう ,然 しか 后 きさき 让awk在 ざい 其余的 てき 参 まいり 数 すう 所 しょ 代表 だいひょう 的 てき 文 ぶん 件 けん 内 ない 寻找该模式 しき 。
~
是 ぜ 用 よう 于检查其两个操作 そうさ 数 すう 是 ぜ 否 ひ 匹 ひき 配 はい 的 てき 运算符 ふ ;其逆则为!~
。注意 ちゅうい 正 せい 则表达式也属于普通 どおり 的 てき 字 じ 符 ふ 串 くし ,可 か 以储存 そん 于变量 りょう 中 ちゅう 。
下面 かめん 的 てき 方法 ほうほう 则采用 よう 了 りょう 在 ざい 命令 めいれい 行 ぎょう 对变量 りょう 赋值的 てき 方法 ほうほう ,即 そく 在 ざい awk的 てき 参 さん 数 すう 中 ちゅう 写 うつし 入 いれ 一 いち 个变量的 りょうてき 值:
$ cat grepinawk
pattern=$1
shift
awk '$0 ~ pattern { print FILENAME ":" $0 }' "pattern=$pattern" $*
$
最 さい 后 きさき ,这种方法 ほうほう 是 ぜ 纯awk的 てき ,无需shell的 てき 帮助,也无需知道 どう 太 ふとし 多 た 关于awk脚本 きゃくほん 实现的 てき 细节(而在命令 めいれい 行 ぎょう 对变量 りょう 赋值的 てき 方法 ほうほう 可能 かのう 与 あずか awk的 てき 实现相 しょう 关);但 ただし 这种方法 ほうほう 的 てき 脚 あし 本有 ほんゆう 点 てん 长:
BEGIN {
pattern = ARGV[1]
for (i = 1; i < ARGC; i++) # 去 さ 除 じょ 第 だい 一 いち 个参数 すう
ARGV[i] = ARGV[i + 1]
ARGC—if (ARGC == 1) { # 模 も 式 しき 是 ぜ 唯一 ゆいいつ 参 さん 数 すう ,因 いん 此强制 きょうせい 从标准 じゅん 输入读取
ARGC = 2
ARGV[1] = "-"
}
}
$0 ~ pattern { print FILENAME ":" $0 }
BEGIN
块的作用 さよう 不 ふ 仅仅是 ぜ 提 つつみ 取出 とりで 第 だい 一 いち 个参数 すう ,也防止 ぼうし 第 だい 一 いち 个参数 すう 在 ざい BEGIN
块结束 たば 后 きさき 直接 ちょくせつ 被 ひ 解 かい 释为输入文 ぶん 件 けん 。ARGC
,输入参 さん 数 すう 的 てき 数量 すうりょう 永 なが 远是不 ふ 小 しょう 于1的 てき ,因 いん 为ARGV[0]
是 ぜ 执行脚本 きゃくほん 的 てき 命令 めいれい 名 めい ,通常 つうじょう 是 ぜ "awk"
。另外,ARGV[ARGC]
永 えい 远是空 そら 串 くし 。对于其中的 てき if
块,它表明 ひょうめい 若 わか 没 ぼつ 有 ゆう 指定 してい 输入文 ぶん 件 けん ,awk会 かい 直接 ちょくせつ 读取标准输入流 りゅう (stdin
)。也即
awk 'prog'
也可以工作 こうさく ,因 いん 为程序 じょ 中 ちゅう 已 やめ 经将ARGC
置 おけ 为了2;若 わか 该值为1,则awk会 かい 认为没 ぼつ 有 ゆう 文 ぶん 件 けん 需要 じゅよう 读取而直接 ちょくせつ 退出 たいしゅつ 。同 どう 时,若 わか 需从标准输入读取数 すう 据 すえ ,需要 じゅよう 将文 まさふみ 件名 けんめい 显式的 てき 指定 してい 为-
。
自 じ 包含 ほうがん 的 てき AWK脚本 きゃくほん [ 编辑 ]
与 あずか 许多其他的 てき 程 ほど 序 じょ 语言相似 そうじ ,可 か 以利用 りよう “shebang ”语法构建自 じ 包含 ほうがん 的 てき awk脚本 きゃくほん 。
例 れい 如,一 いち 个名为hello.awk
,可 か 以输出 で “Hello, world!”的 てき UNIX命令 めいれい 可 か 以通过建立 こんりゅう 内容 ないよう 如下,名 めい 为hello.awk
的 てき 文 ぶん 件 けん 来 らい 完成 かんせい :
#!/usr/bin/awk -f
BEGIN { print "Hello, world!" }
-f
参 まいり 数 すう 告 つげ 诉awk将 はた 该文件 けん 作 さく 为awk的 てき 程 ほど 序文 じょぶん 件 けん ,然 しか 后 きさき 即 そく 可 か 运行该程序 じょ 。
^ 1.0 1.1 Andreas J. Pilavakis. UNIX Workshop. Macmillan International Higher Education. 1989: 196.
^ 2.0 2.1 Arnold Robbins. Effective Awk Programming: Universal Text Processing and Pattern Matching 4th. O'Reilly Media. 2015: 560.