awk详解

本文深入介绍awk,一个在Linux/Unix环境下的强大命令行工具。内容涵盖awk的基本语法、值域、程序规则,包括正则模版、一般表达式模版、内置变量和awk脚本的使用。通过实例解析awk在文本过滤和处理中的应用。

系列文章目录

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-file1inpit-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, $2line, $5awk.
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表达式

仍然使用之前的邮箱列表,我们可以打印出从 BillMartin的所有行

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

四.参数文献

  1. The GNU Awk User’s Guide

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JintGuo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值