文本处理-awk

awk既是一个shell工具,也是一门编程语言,linux和osx下都可以直接用,windows下有gawk(下载链接)。

以下内容参考mawk用户手册(man awk),可能与标准awk语言有出入

一、工作原理

  1. awk扫描输入的每一行(记录分隔符RS, record separator),
  2. 每行会被分隔成若干个域(域分隔符FS, field separator),
  3. 根据pattern匹配每一行,
  4. 如果匹配就执行action

二、awk解释器

程序文件

  • 短的程序内容可以用单引号包括,直接在命令行中运行;
    awk '{print $1}' text_file
  • 长的程序文件可以通过-f参数指定路径。
    awk -f awk_program_file text_file

文本文件

  • awk可以接收多个文件路径作为输入
  • awk可以接收管道输出作为输入
  • 如果没有指定上面两者,awk对标准输出进行处理

mawk命令行

mawk [-W option] [-F value] [-v var=value] [--] 'program text' [file ...]
mawk [-W option] [-F value] [-v var=value] [-f program-file] [--] [file ...]

三、awk编程语言

1). 程序结构

awk程序包含若干pattern {action}序列函数定义

  1. patternaction不能同时省略
  • pattern可以省略,如果省略,默认匹配成功
  • action可以省略,如果省略,默认为print
  1. pattern可以为
  • BEGIN 匹配文本文件开始位置, 其action不能为空
  • END 匹配文本文件结束位置,其action不能为空
  • expression 单个表达式
  • expression, expression 多个表达式
  1. 其他语句
  • 语句结束符为新行或者分号;
  • 一个语句块由大括号包围;
  • 一条语句可以使用反斜杠进行跨行;
  • 注释由#开头
  1. 流程控制语句
if ( expr ) statement
if ( expr ) statement else statement
while ( expr ) statement
do statement while ( expr )
for ( opt_expr ; opt_expr ; opt_expr ) statement
for ( var in array ) statement
continue
break

2). 数据类型

awk有两种基本数据类型:

  1. 数字型
  • 可以为整数 2, -2
  • 可以为小数 0.5
  • 可以为科学表示法数字 0.2e8 1.2E5

所有数字内部由浮点数进行表示和计算,true表示为1.0

  1. 字符型
  • 字符串用双引号包括 "a string"
  • 特殊字符可以由反斜杠\转义

3). 正则表达式

正则表达式由斜杠包括/r/

  • 匹配操作符~ 右侧可以为一个表达式
  • 非匹配操作符!~ 右侧可以为一个表达式
    pattern-action对可以这样表示:
    /r/ {action}$0 ~ /r/ {action}

4). 记录和域

  • 每次记录(record, 行)存储在域(field)$0中,
  • 每行被分隔为多个域,分别存在$1, $2, ... $NF中,
  • NF(number of fields)被设置为域的数量,
  • NRFNR递增

5). 表达式和操作符

基本表达式

  • 数字常量
  • 字符串常量
  • 变量
  • 数组
  • 函数调用

变量、数组和函数命名可以为字符、数字、下划线,不能以数字开头。
变量不用声明,第一次使用会被初始化为null

操作符:

assignment          =  +=  -=  *=  /=  %=  ^=
conditional         ?  :
logical or          ||
logical and         &&
array membership    in
matching       ~   !~
relational          <  >   <=  >=  ==  !=
concatenation       (no explicit operator)
add ops             +  -
mul ops             *  /  %
unary               +  -
logical not         !
exponentiation      ^
inc and dec         ++ -- (both post and pre)
field               $

6). 数组

awk可以表示一维数组array[expr], expr会被转换为字符串类型。

  • 成员检查 expr in array 在返回1,否则返回0
  • 下标遍历 for(var in array)
  • 删除成员 delete array[expr]
  • 多维数组 array[expr1, expr2]等于 array[expr1 SUBSEP expr2]
    • 成员测试 if( (i, j) in array) print array[i, j]

7). 内建变量

变量名 含义 缩写
ARGC 参数数量
ARGV 参数数组
CONVFMT 内部数字转字符串格式,默认为%.6g
ENVIRON 环境变量数组
FILENAME 当前输入文件
FNR 当前记录编号 file record number
FS 域分隔符 field separator
NF 域数量 number of fields
NR 当前记录编号 record number
OFMT 数字输出格式, 默认%.6g output format
OFS 输出域分隔符,默认空格 output field separator
ORS 输出记录分隔符 默认\n output record separator
RLENGTH 最近一次match调用的长度
RSTART 最近一次match调用得到的下标
RS 输入记录分隔符 record separator
SUBSEP 多维数组下标分隔符,默认\034 subscript separator

8). 内建函数

字符串函数 含义 算术函数 含义
gsub(r, s[, t]) 字符串替换 atan2(y, x)
index(s, t) 返回子串位置 cos(x)
length(s) 返回字符串长度 exp(x)
match(s, r) 返回首个匹配位置 int(x) 取整
split(s, A[, r]) 分隔s到A数组 log(x)
sprintf(format, expr-list) rand() 0-1之间随机数
sub(r, s[, t]) 替换一次 sin(x)
substr(s, i[, n]) 返回子串 sqrt(x)
tolower(s) 返回小写形式 srand([expr]) 根据种子随机
toupper(s) 返回大写形式

9). 输入输出

输出语句:

  • print
  • print expr1, expr2, ..., exprn
  • printf format, expr-list

输入语句:

  • getline 读取一行
  • getline < file 从文件读取一行
  • getline var 读到var
  • getline var < file 从文件读到var
  • command | getline 从管道读取一行
  • command | getline var 从管道读到var

其他语句:

  • close(expr) 关闭文件
  • fflush(expr) 刷新输出文件
  • system(expr) 执行expr

10). 自定义函数

格式:

function name(args) { statements }

可以有返回值,但不必须:

return opt_expr

传入参数和局部变量参数之间使用多个空格分隔(惯例)

11). 字符串、记录、文件分隔

同一种分隔算法:split(expr, A, sep)

12). 多行记录

设置RS

13). 程序执行

  • ARGC被设置为命令行参数数目,ARGV[0]被设置为awk解释器,ARGV[i]被设置为其余命令行参数
  • 然后BEGIN语句块被依次执行。如果只有BEGIN语句,程序结束;否则打开输入流。如果ARGC=1,输入流被设置为stdin。然后ARGV[i]将被作为文件参数检查。
  • 命令行参数可分为三类:文件参数、赋值参数、空字符串。赋值参数格式为var=string。如果ARGV[i]可能是个文件参数,如果为空就跳过;如果是赋值参数,就会设置var的值,然后跳到下个参数;否则ARGV[i]作为输入打开。如果打开失败,程序结束,返回错误码2。如果没有参数是文件参数,输入从stdin获取。在BEGINgetline会打开输入,-表示stdin
  • 输入流打开之后,每条输入记录都会与pattern进行匹配。如果匹配,相关的action就会执行。表达式模式为true时才匹配。BEGIN匹配在任何输入读取之前匹配,END在所有输入读取结束之后匹配。范围表达式expr1, expr2匹配两个表达式分别匹配的行之间所有行,并包含这两个匹配行。
  • 当输入流的文件结束时,其余的命令行参数会被检查是否是文件参数,如果有就会被打开,重复上一步骤。如果没有,END模式会被匹配,所有的ENDaction都会被执行。
  • pattern {action}层次的程序流程可以被一下语句改变:
    • next
    • exit opt_expr

其他参考

酷壳
man awk

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,980评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,178评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,868评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,498评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,492评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,521评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,910评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,569评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,793评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,559评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,639评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,342评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,931评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,904评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,144评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,833评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,350评论 2 342

推荐阅读更多精彩内容

  • 转载 原文的排版和内容都更加友好,并且详细,我只是在这里贴出了一部分留作自己以后参考和学习,如希望更详细了解AWK...
    XKirk阅读 3,185评论 2 25
  • awk: grep,sed,awk grep:文本过滤 sed:文本编辑 awk:文本格式化工具; 1 什么是aw...
    木林森阅读 1,763评论 0 16
  • awk介绍awk变量printf命令:实现格式化输出操作符awk patternawk actionawk数组aw...
    哈喽别样阅读 1,546评论 0 4
  • netstat -tnlp|egrep -i "$1"|awk {'print $7'}|awk -F'/' '{...
    JerichoYu阅读 986评论 0 0
  • linux资料总章2.1 1.0写的不好抱歉 但是2.0已经改了很多 但是错误还是无法避免 以后资料会慢慢更新 大...
    数据革命阅读 12,127评论 2 34