awk笔记

AWK 简介

基本概念

  • awk 语言由 Aho, Kernighan and Weinberger(1988) 提出,适合于数据文件和文本批量处理和格式化的场景,提供变量和函数的概念,并有许多内建函数和变量,对正则表达式提供良好的支持。
  • mawk 为实验环境的 awk 语言解释器。

基本命令形式

awk 'pat1{hadle1} pat2{hadle2} ... ' file

pattern{hadle block}: 为awk程序的基本组成元素,awk 程序运行过程中,待处理的数据流会被 RS(Record Separator) 变量分割为逐个的 record,每个 record 会逐个与各个模式进行匹配,当匹配成功时,对应的处理模块会执行,缺省的分隔符为 \n,缺省的处理模块为 { print($0) } 打印当前 record。

$ cat test.txt 
1 a
2 bc
3 def
4 ghij
5 klmno
$ awk 'BEGIN{ print "line word"} /^1/{print} /^3/{print} END{print "end..."}' test.txt 
# BEGIN 及 END 为一种特殊的 PATTERN
line word
1 a
3 def
end...

命令参数

-f 指定 awk 程序文件

awk -f awk_code_file file_to_handle... 简单的awk程序可以直接写在命令行中,形如 awk 'awk_code' file_to_handle...,复杂的代码可以保存为代码文件,用 -f 指定,见 awk语言基础 > 执行方式 小节

-F 指定分隔符

默认 Record Separator = "\n" 可以自定义,在本机( mawk 1.3.3 @ ubuntu 16.04.10)该参数不生效

设置 RS 变量

可以通过直接设置 RS 变量达到改变分割符的目的

$ cat test.txt 
1 a - 2 bc - 3 def - 4 ghij - 5 klmno
$ awk 'BEGIN{ RS="( - )?[0-9]"} {print($0)}' test.txt 
# 支持正则表达式作为分隔符
 a
 bc
 def
 ghij
 klmno

-v 变量赋值

-v var=value assigns value to program variable var.

将外部环境变量传递到 awk 程序

$ RS=[0-9]
$ awk -v RS=${RS} 'BEGIN{print RS} {print($0)}' test.txt 
[0-9]

 a - 
 bc - 
 def - 
 ghij - 
 klmno

$ awk 'BEGIN{print RS} {print($0)}' RS=$RS test.txt 

 a - 
 bc - 
 def - 
 ghij - 
 klmno

pattern

A pattern can be:

  • BEGIN : 可选,在输入流读取之前执行,一般用来完成变量初始化、打印输出表头等操作。
  • END : 可选,在输入流处理完毕执行,一般用来完成统计结果。
  • expression : 变量的判断语句 或 record的正则匹配语句
  • expression , expression : 表达式的pattern1,pattern2形式称为范围模式。 它匹配所有输入记录,从与pattern1匹配的记录开始,并持续到与pattern2匹配的记录(包括)。 它不与任何其他类型的模式表达式组合。当有重复行时,范围模式会将重复结果显示, 见关于awk的范围模式功能问题
$ seq 15 | awk '/1$/,/4$/{print $0}' # 正则遇上重复行,行为比较复杂,慎用
1
2
3
4
11
12
13
14
$ seq 15 | awk 'NR==1,NR==4{print $0}' # 选择行范围就很方便
1
2
3
4

处理代码块

awk 语言基础

AWK程序设计语言

执行方式

  • awk 'simple code' file1 file2 ...: 对多个 file 输入执行简单的处理命令
  • awk -f awk_code_file file1 file2 ...: 对多个 file 输入执行复杂的处理脚本
  • awk 'simple code' k1=v1 k2=v2 file1 file2 ...: 指定awk长徐运行的命令行参数

内建变量

变量 含义 备注
NR 当前行号 -
NF 当前行的字段数 -
$0 当前行的内容 -
$n 当前行的第n个字段 -
$ awk 'BEGIN{ print "line\tNR\tcontent"} {printf "%d\t%d\t%s\n", NR, NF, $2 } END{print "end ..."}' test.txt 
line    NR  content
1   2   a
2   2   bc
3   2   def
4   2   ghij
5   2   klmno
end ...

内建函数

函数 说明 备注
length(str) 字符串长度 -
index(str, subStr) 字符串索引 -
split(str, arr, delimiter) 字符串分割 -
substr(str, start, end) 提取子串 -
sub(regex, replace_str, string) 正则替换首个子串 -
gsub(regex, replace_str, string) 全局正则替换子串 -
match(regex, string) 正则匹配 -
printf( format, ... ) 打印 -
$ cat test.awk 
$ cat test.awk 
BEGIN{ 
    print( "line\t" "$2\t" "length\t" "index of a\t" "subStr(0-3)") 
} 

{ # show the basic usage of length, index and substr
    printf("%d\t" "%s\t" "%d\t" "%d\t\t" "%s" "\n", 
        NR, 
        $2, 
        length($2), 
        index($0,"a"), 
        substr($0,1,3) );
}

{ # show the basic usage of split, match and sub
    if( match( $0, "h.*$" ) ){
       split( $0, arr, "h" );
       mat = substr($0, RSTART, RSTART+RLENGTH)
       printf("get character %s, %s -- %s\n", mat, arr[0], arr[1] );
       replace = "-" mat;
       sub( "h.*$", replace, $0);
       print($0); 
    };
}

{ # show the basic usage of gsub
    printf( "%s ==> ", $0 )
    gsub( "[a-z]", "-", $0 );
    print($0);
}

END{
    print("end ...")
}
$ awk -f test.awk test.txt 
line    $2  length  index of a  subStr(0-3)
1   a   1   3       1 a
1 a ==> 1 -
2   bc  2   0       2 b
2 bc ==> 2 --
3   def 3   0       3 d
3 def ==> 3 ---
4   ghij    4   0       4 g
get character hij,  -- 4 g
4 g-hij
4 g-hij ==> 4 -----
5   klmno   5   0       5 k
5 klmno ==> 5 -----
end ...

数据类型

  • 数值形常量, 支持 整形、浮点和科学计数法,数值型计算过程自动转换为 float. 布尔型 true = 1.0
  • 字符串常量, 双引号包围,特殊字符需要转义
  • 变量,用户自定义变量同时具有数值型值和字符串型值,随计算需要自动进行转换,并且在第一次引用时自动创建,初始值为 null,数值为0,字符串值为""

隐式转换

The type of an expression is determined by its context and automatic type conversion occurs if needed.  For example, to evaluate the statements
表达式的类型有内容决定,必要时会执行隐式转换。
y = x + 2  ;  z = x  "hello"
x为变量,可以转换为数值型,2为数值型,因此y为数值型,“hello”为字符串型,x可以转换为字符串型,因此z为字符串型。
字符串转换为数字通过函数 atof, 反之通过 sprintf
In boolean contexts such as, if ( expr ) statement, a string expression evaluates true if and only if it is not the empty string ""; numeric values if and only if not numerically zero.
空字符串和0为假,其他为真

数组

基本操作

$ seq 5 | awk '{arr[NR]=$0} END{ for(l in arr) print l "-" }'
1-
2-
3-
4-
5-

迭代器

for ( var in array ) statement

语句

同 C,且 # 开始的行为注释

控制语句,if for

  • 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

正则

Linux基础之-正则表达式(grep,sed,awk)

正则比较运算符str ~ /pattren/

运算符

  • 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 $

自定义函数

$ cat fun_test.awk 
function hello(n) { return "hello " n }
{ print( hello($0)) }
$ seq 2 | awk -f fun_test.awk 
hello 1
hello 2

杂项

awk命令行参数

$ awk 'BEGIN{print RS} {print($0)}' RS=$RS test.txt # RS为命令行参数 

 a - 
 bc - 
 def - 
 ghij - 
 klmno

获取其他bash命令输出

echo | awk '{ "expression_shell_cmd" | getline cmdout; statement... }'

鸡肋

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

推荐阅读更多精彩内容

  • 转载 原文的排版和内容都更加友好,并且详细,我只是在这里贴出了一部分留作自己以后参考和学习,如希望更详细了解AWK...
    XKirk阅读 3,149评论 2 25
  • awk: grep,sed,awk grep:文本过滤 sed:文本编辑 awk:文本格式化工具; 1 什么是aw...
    木林森阅读 1,708评论 0 16
  • Linux指令中文说明传送入口 整理自Linux指令中文说明 文本和数据进行处理的编程语言awk 是一种编程语言,...
    释闲人阅读 2,038评论 1 6
  • 本文大部分内容翻译自我开始学习AWK时看到的一篇英文文章 AWK Tutorial ,觉得对AWK入门非常有帮助,...
    mylxsw阅读 1,148评论 0 12
  • 官网 中文版本 好的网站 Content-type: text/htmlBASH Section: User ...
    不排版阅读 4,313评论 0 5