Awk

awk 是一种用于文本处理的解释性程序设计语言

基本语法

一个awk指令由一个模式(pattern)后跟一个动作(action)组成。

1
awk pattern1 {actions1} pattern2 {actions2}

awk可以直接在命令行中运行,也可以将指令放在文件中运行。awk常用选项如下:

  • -F ‘ ‘ : 指定输入数据的列分隔符
  • -v var=value : 在awk程序中定义变量var
  • -f programFile : 指定awk程序文件,代理在命令行指定awk指令

特殊变量

  • FS : 目前的分隔字符,默认是空白键
  • NR : 表示记录数量(number of records),在执行过程中对应于当前行号
  • NF : 表示字段数量(number of fields),在执行过程中对应于当前行的字段数
  • $0 : 这个变量包含执行过程中当前行的文本内容
  • $1 : 这个变量包含第一个字段的文本内容

将外部变量值传递给awk

1
2
3
4
5
# 借助选项 -v ,我们可以将外部值(并非来自stdin)传递给 awk
awk -v VARIABLE=$VAR'{ print VARIABLE }'

# 直接在指令后定义变量
awk '{ print VARIABLE }' VARIABLE=$VAR

设置字段分隔符

1
2
3
4
5
# 使用 -F 选项指定分隔符
awk -F: '{ print $NF }'

# 在 BEGIN指令中设置 FS特殊变量
awk 'BEGIN {FS=":"}'

对行进行过滤

1
2
3
4
5
awk 'NR < 5'        # 行号小于5的行
awk 'NR==1,NR==4' # 行号在1到5之间的行

awk '/linux/' # 包含样式linux的行(可以用正则表达式来指定样式)
awk '!/linux/' # 不包含包含样式linux的行

用 getline 读取行

通常, grep 默认读取一个文件的所有行。如果只想读取某一行,可以使用 getline
语法: getline var
变量 var 就包含了特定行的内容

1
seq 5 | awk 'BEGIN { getline; print "Read ahead first line", $0 } { print $0 }'

从 awk 中读取命令输出

1
echo | awk '{ "grep root /etc/passwd" | getline cmdout ; print cmdout }'

if语句

1
seq 5 |awk '{if( NR < 3 ){ print $1 }}'

for循环语句

1
echo |awk '{for(i=1; i<=5; i++){ print i }}'

内建字符串控制函数

length(string)
返回字符串的长度

1
2
[gavin@localhost ~]$ echo 'a|bb|ccc' |awk -F '|' '{printf $1; print length($1)}'
a1

index(string, search_string)
返回 search_string 在字符串中出现的位置

1
2
[gavin@localhost ~]$ echo 'abcd' |awk '{print index($0, "a")}'
1

split(string,array,delimiter)
用定界符生成一个字符串列表,并将该列表存入数组

1
2
[gavin@localhost ~]$ echo 'a|bb|ccc' |awk '{print split($0, array, "|")}'
3

substr(string, start-position, end-position)
在字符串中用字符起止偏移量生成子串,并返回该子串

1
2
[gavin@localhost ~]$ echo 'abc' |awk '{print substr($0, 1, 1)}'
a

sub(regex, replacement_str,string)
将正则表达式匹配到的第一处内容替换成 replacment_str

1
2
[gavin@localhost ~]$ echo 'abc123' |awk '{sub("[a-z]", 0, $0); print $0}'
0bc123

gsub(regex, replacment_str, string)
和 sub() 类似。不过该函数会替换正则表达式匹配到的所有内容

match(string, regex)
检查正则表达式是否能够匹配字符串。如果能够匹配,返回非0值;否则,返回0。 match() 有两个相关的特殊变量,分别是 RSTART 和RLENGTH 。变量 RSTART 包含正则表达式所匹配内容的起始位置,而变量 RLENGTH 包含正则表达式所匹配内容的长度

1
2
3
4
[gavin@localhost ~]$ echo 'abc123' |awk '{result=match($0, "[a-z]+"); print result; print RSTART; print RLENGTH}'
1
1
3