系列文章目录
awk详解, 持续更新中
文章目录
前言
awk作为linux/unix命令行下的常用工具,不仅在日常工作中经常使用到,也是面试中经常会出现的考察点。该篇文章深入介绍awk的使用。有描述错误的地方欢迎指出。
一、awk是什么?
awk 是gun重要的命令行工具。该工具按照一定的模版(pattern)过滤文件的每一行,当模版匹配上后,执行定义的动作(action)。每一对pattern和action称作一个规则(rule)。规则的定义形式为
pattern { action }
pattern { action }
…
二、如何使用awk
1. 基本语法
awk 的基本语法如下
awk 'program' input-file1 input-file2
- program 为一个或者多个的
rule(即pattern/action对)。 program 也可以通过可选参数-f从文件中读取,后续章节中会详细介绍。 - input-file 为awk操作的文件对象(也可以是标准输入
stdin)。awk可以同时过滤多个文件,如此处的input-file1、inpit-file2
2. file
file 是awk的过滤对象可以一个、多个文件,甚至为空。当不指定file时,awk从标准输入stdin中读取每一行
awk '{ print }'
line1 << 键盘输入
line1 << "print" 的打印
line2 << 键盘输入
line2 << "print" 的打印
2.1 值域(field)
awk读取文件的每一行时,该行会被自动拆分成多个值域(field)。 默认情况下,field是根据空白符进行拆分(一个或者多个空格,一个或多个制表符)。 可以通过$ 对field进行引用。例如我们有如下行
A line example for awk.
$1 为值 A, $2 为line, $5 为awk.
awk 的内置变量 NF 存储field个数,在该例下NF 的值为5. 我们可以直接使用 $NF 来获取到最后一个field的值 awk.
$0 的值为当前整行
➜ echo A line example for awk. | awk '{ print $0 }' # 如章节TODO描述,pattern可以为空
A line example for awk.
➜ echo A line example for awk. | awk '{ print $1 }'
A
➜ echo A line example for awk. | awk '{ print $2 }'
line
➜ echo A line example for awk. | awk '{ print $5 }'
awk.
➜ echo A line example for awk. | awk '{ print $NF }'
awk.
3. program
program为rule的组合,可以包含一个、多个rule。
仅包含一个rule时为
awk 'pattern { action }' file
当包含多个rule时,通常每个rule占据一行
awk 'pattern { action }
pattern { action }' file
3.1 pattern
pattern 可以是以下几种类型
- 正则模版(regexp patterns)
- 一般表达式模版(expression patterns)
- 空
- 范围(ranges)
- 开始/介绍(BEGIN/END)
3.1.1 正则模版(regexp patterns)
假设我们有一个文件存放了邮箱账号,我们想通过awk来打印所有的qq邮箱,那么我们可以通过以下命令
➜ cat email
Johnie@qq.com
Edward@gmail.com
Tom@qq.com
Cathy@qq.com
Tina@126.com
➜ awk '/qq\.com/ { print$0 }' email
Johnie@qq.com
Tom@qq.com
Cathy@qq.com
pattern是 /qq\.com/ , /<regex>/ 正则表达式写在两个斜杠中
print$0 为action,写在花括号内,打印匹配上pattern的整行。print 以及$0 的具体含义我们会在后续章节xxx 中介绍。
3.1.2 一般表达式模版(expression patterns)
任何的awk表达式都可以作为awk的pattern(我们将在后续章节XXX对awk表达式作深入介绍)。只要表达式的返回结果非零或者非空,那么即代表pattern匹配上。 例如我们有以下邮箱列表:
➜ cat mail
Anthony anthony.asserturo@hotmail.com
Becky becky.algebrarum@gmail.com
Bill bill.drowning@hotmail.com
Camilla camilla.infusarum@skynet.be
Fabius fabius.undevicesimus@ucb.edu
Martin martin.codicibus@hotmail.com
Jean-Paul jeanpaul.campanorum@nyu.ed
我们可以通过比较表达式(Comparison expressions)读取Bill 的邮箱
➜ awk '$1 == "Bill" { print $2 }' mail
bill.drowning@hotmail.com
我们也可以通过正则表达式(Regexp)来获取名字中包含il的邮箱
➜ awk '$1 ~ /il/ { print $2 }' mail
bill.drowning@hotmail.com
camilla.infusarum@skynet.be
此处要区分正则模版和正则表达式, 如果是用正则模版
➜ awk '/il/ { print $2 }' mail
anthony.asserturo@hotmail.com
becky.algebrarum@gmail.com
bill.drowning@hotmail.com
camilla.infusarum@skynet.be
martin.codicibus@hotmail.com
该条正则模版因为没有$1的范围限制,会匹配所有包含il 的行
3.1.3 空
pattern 可以为空。为空时所有的行都被匹配上,执行action
➜ awk '{ print $2 }' mail
anthony.asserturo@hotmail.com
becky.algebrarum@gmail.com
bill.drowning@hotmail.com
camilla.infusarum@skynet.be
fabius.undevicesimus@ucb.edu
martin.codicibus@hotmail.com
jeanpaul.campanorum@nyu.edu
3.1.4 范围(ranges)
范围模版指定过滤范围,基本写法为
awk 'begpat, endpat' file
begpat 标识开始过滤的行, endpat 标识结束过滤的行 begpat/endpat 的内容为awk表达式
仍然使用之前的邮箱列表,我们可以打印出从 Bill 到 Martin的所有行
➜ cat mail
Anthony anthony.asserturo@hotmail.com
Becky becky.algebrarum@gmail.com
Bill bill.drowning@hotmail.com
Camilla camilla.infusarum@skynet.be
Fabius fabius.undevicesimus@ucb.edu
Martin martin.codicibus@hotmail.com
Jean-Paul jeanpaul.campanorum@nyu.edu
➜ awk '$1 == "Bill", $1 == "Martin" { print $2 }' mail
bill.drowning@hotmail.com
camilla.infusarum@skynet.be
fabius.undevicesimus@ucb.edu
martin.codicibus@hotmail.com
3.1.5 开始/结束(BEGIN/END)
BEGIN, END 是两个特殊的patter,分别用来表示awk开始过滤文本之前,以及过滤文本之后,并且这两个pattern一定要有action(后续章节我们将介绍到action可以为空,但此处为例外见章节XXX)。
仍然使用之前的邮箱列表
➜ awk '$1 ~ /il/ { ++n }
BEGIN { print "Before filter..." }
END { print " \"li\" apprears", n, "times" }' mail
Before filter...
"li" apprears 2 times
我们可以通过一般表达式模版 来统计li 出现的次数,最终END 来打印统计结果
3.2 action
action定义pattern匹配上之后的操作。action 定义在{ } 内,可以是一条、多条awk语句(statement),甚至可以为空。当为空时, 分为两种情况:
➜ awk '/il/ { }' mail
➜ awk '/il/' mail
Anthony anthony.asserturo@hotmail.com
Becky becky.algebrarum@gmail.com
Bill bill.drowning@hotmail.com
Camilla camilla.infusarum@skynet.be
Martin martin.codicibus@hotmail.com
'/il/' 执行默认的操作{ print $0 }
'/il { }' 不执行任何操作
statement 可以是以下几种类型:
- awk表达式(expression)
- 条件语句 (Control statements)
- Compound statements
- Input statements
- Output statements
- Deletion statement
2. awk表达式(expression)
TODO
3. 进阶使用
TODO
3.1 内置变量
3.2 awk 脚本
#! /bin/awk -f
BEGIN { print "Don't Panic!" }
三. 常用示例
# TODO
本文深入介绍awk,一个在Linux/Unix环境下的强大命令行工具。内容涵盖awk的基本语法、值域、程序规则,包括正则模版、一般表达式模版、内置变量和awk脚本的使用。通过实例解析awk在文本过滤和处理中的应用。

1629

被折叠的 条评论
为什么被折叠?



