title: awk 命令介绍
date: 2018-01-09 18:17:16
tags: [Linux, awk]
categories: Linux

awk是什么

awk是一种处理文本文件的语言。是的,这是一门编程语言。是由Alfred Aho, Peter Weinberger, 和 Brian Kernighan三位创造的,语言名称取自三位姓氏的首字母。目前我们使用的一般是gawk,是awk的GNU版本。

awk模式

awk是由一系列的模式-动作对组成的

1
pattern { action }

其中pattern是awk在数据中查找的内容格式,action是在查找到之后执行的一系列命令。

awk以行为单位进行处理,默认使用空格作为分隔符分割行,分割出来的域可以使用\$1,\$2等来使用,\$0代表整行的内容

pattern我们常用的有BEGINEND,分别表示在读取所有记录的之前和之后

awk 的pattern

任意的awk表达式都是有效的awk模式,我们在这列举几个常用的。

pattern 说明
BEGIN 在读取所有记录之前执行,只执行一次
/regexp/ 在一行中匹配正则表达式
END 在读取完所有记录后执行,只执行一次
$1 == “root” 判断某个域是否等于某值
$1 ~ /regexp/ 完整正则写法,不带~时匹配整行
\$1 == “root” 丨丨 $1 == “lee” 或运算和与运算(&&)
!/regexp/ 非运算,完整的正则将(~)替换为(!~)

awk的action

action其实就是我们要执行的语句, 风格继承自C语言,其中也混杂了一些Linux上的概念,我们可以很快的上手

下面列举几个比较常用的

action 说明
print $1 打印到屏幕
printf(“first field is %s”, $1) c语言风格的打印函数
print func(args) 调用函数

基本我们使用的就是这两个,action中也可以定义变量,标准与c语言一致

1
变量名可以是语言关键字外的,只包含大小写拉丁字母,数字和下划线(“_”)的任意字。而操作符“+ - * /”则分别代表加,减,乘,除。简单的将两个变量(或字符串常量)放在一起,则会将二者串接为一个字符串。若二者间至少有一个是常量,则中间可以不加空格;但若二者均为变量,中间必须包括空格。字符串常量是以双引号("")分隔的。另外,注释是以“#”开头的。

譬如统计文件行数awk 'BEGIN {count=0} {count++} END {print count}' file
多条语句写在一行上我们需要使用分号来隔开,如果只有一条语句,分号并不是必须的。
譬如输出两行语句awk 'BEGIN {print "Hello"; print "World"}'

awk可以自定义函数,可以使用循环,可以说是图灵完备的,平常我们也不会用它来处理太复杂的逻辑,大家有兴趣的可以看看。

awk内置变量

awk内部保存了很多有用的状态变量,我们可以随时拿来使用,像上面举的文件行数的例子,awk已经给我们准备好了

内置变量 说明
NR 已读取记录的条数(number of input records)
NF 当前记录中field的个数 (number of fields in an input record) 最后一个域可以以$NF的方式引用
FILENAME 当然输入文件的文件名
FS 域分隔符 (field-separator),默认空格
RS 行分隔符(record-separator) 默认是\n
OFS 输出域分隔符(output field separator),默认空格
ORS 输出记录分隔符(output record separator),默认\n
OFMT 输出数字格式(Format for numeric output)其默认值为”%.6g”

awk 常用举例

Hello world

awk ‘BEGIN {print “Hello world”}’

行数,单词数,字符数(wc功能)

awk ‘{w += NF; c += length($0) + 1} END {print NR, w, c}’

输出奇数行

awk ‘NR % 2 == 1 {print NR, $0}’