[linux工具] awk

awk是一种模式匹配的编程语言,它的主要功能是匹配文本并对其进行处理,同时它有一些编程语言才有的语法,如函数、分之、循环、变量、数组等。awk的数据可以来自标准输入、文件或其他命令的输出。

一、awk基础
  • 1.1 语法形式
awk [options] 'script' var=value file(s)
awk [options] -f scriptfile var=value file(s)

其中常用的options选项如下:

options描述示例
-F指定字段分隔符,fs可以是字符串或正则表达式echo "1:2:3" | awk -F: '{print $1 ", " $2 ", " $3}'
-v定义一个用户自定义的外部变量var,变量赋值发生在awk处理文本前awk -v a=1 -v b=2 'BEGIN {print "a = " a ", b = " b}'
-f指定awk脚本所在的脚本文件echo "1\n2\n3\n4\n5" | awk -f plusscript.awk

注:上述plusscript.awk文件内容

BEGIN{ i = 0}
{i += $1}
END{print i}

语法中script或scriptfile文件中内容一般由多个pattern和action序列组成,当读入记录匹配pattern时,才会执行相应的action操作。

  • 1.2 模式(pattern)

其中pattern有以下几种情况:

模式类型描述使用示例
/正则表达式/扩展的正则表达式awk '/Jerry/{print $0}' awktest.txt #输出匹配Jerry的行
关系表达式使用运算符进行操作,可以是字符串或数字的比较测试awk 'NR % 2 == 0 {print $0}' awktest.txt #输出偶数行
BEGEIN特殊模式,在第一条记录前被执行,常用语初始化语句awk -v var="test var" 'BEGIN{print var}' #输出变量var
END特殊模式,在最后一个记录处理后被执行,常用语输出汇总信息echo "1\n2\n3\n4\n5" | awk 'END{print NR} #输出记录数'
pattern,pattern模式对,匹配两者之间的所有记录,类似sed的地址对awk '/Lucy/,/Amy/{print$0}' awktest.txt #输出匹配Lucy与匹配Amy之间的所有行

注:awktest.txt文件内容

Jerry, 22, PEK
Lucy, 21, SHA
Lily, 23, CAN
Amy, 22, SZX
Angel, 20, TSA
  • 1.3 操作(action)

action操作由一个或者多个命令、函数、表达式组成,位于大括号内,多个之间由换行符或分号隔开,主要组成部分包括:变量或数组赋值、运算符、输出命令、内置函数、控制语句

【预定义变量】

awk的主要内置变量(预定义变量)如下

变量名描述使用示例
$n当前记录的第n个字段,n从1开始echo '1:2:3' | awk -F: '{print $1 ", " $2 ", " $3}' #字段间无逗号分隔则输出无分隔符
$0当前记录的整行文本内容echo '1:2:3' | awk -F: '{print $0}'
ARGC命令行参数个数,即ARGV的数组长度awk 'BEGIN{print "ARGC=" ARGC "\nP1=" ARGV[0] "\nP2=" ARGV[1]}' awktest.txt
ARGV命令行参数数组
FILENAME当前输入文件名awk 'END{print FILENAME}' awktest.txt
FS字段分隔符,默认为空格awk 'BEGIN{FS=":"} {print $1} END{print FNR}' awktest.txt
NF表示字段数echo '1:2:3' | awk -F: '{print $NF-1}' #输出倒数第二个字段
NR表示记录数,执行过程中表示当前行号awk 'END{print NR}' awktest.txt #输出文件记录数
OFS输出字段分隔符,默认为空格echo '1:2:3' | awk -F: 'BEGIN{OFS="***"} {print $1,$2,$3}'
ORS输出记录分隔符,默认为换行符echo '1\n2\n3' | awk 'BEGIN{ORS="\n---\n"} {print $0}'
RS记录分隔符,默认为换行符echo '1:2:3' | awk 'BEGIN{RS=":";ORS="\n***\n"} {print $0}'
CONVFMT定义数值转换为字符串的格式,默认为"%.6g",注:适用于gawkawk 'BEGIN{CONVFMT="%d"; printf "CONVFMT=%s, num=%f, str=%s", CONVFMT, 24.22, 24.22}'
OFMT定义输出时数值转换成字符串的格式,默认为"%.6g",注:适用于gawkawk 'BEGIN { OFMT="%d";print 12.1222222 }'
RSTART由match函数匹配的字符串的第一个位置awk 'BEGIN{match("this is my son", "s m"); print RSTART, RLENGTH}'
RLENGTH由match函数匹配的字符串的长度

【自定义变量】

awk有两种自定义变量的形式,一种是通过option参数-v指定,另一种是通过在操作语句中声明的变量,如下:

echo | awk 'BEGIN{var="abcde"} {} END{print var}'
---
abcde

echo | awk -v var="abcde" 'END{print var}'
---
abcde

【数组】

数组是一种特殊的变量,awk中的数组都是关联数组,它的下标是字符串,数组的赋值方式:array[index]=value,数组的遍历可以通过for...in...的语法,同时in也可以用于if分之判断中元素是否在数组中,是则返回1,否则返回0。

echo "1:2:3" | awk -F: '{for(i=1;i<4;i++) a[i]=$i} END{for(i in a) printf "a[%s] = %s\n", i, a[i]; if(3 in a) print "3 in a"; if(5 in a) print "5 in a"}'
---
a[1] = 1
a[2] = 2
a[3] = 3
3 in a

【运算符】

运算符类型运算符描述
算术运算符
+, -加, 减
*, /, &乘,除,与
^, **求幂
a++, ++a, a–, --a自增,自减
赋值运算符
=, +=, -=, *=, /=, %=, ^=, **=赋值运算符
逻辑运算符
||逻辑或
&&逻辑与
!逻辑非
正则运算符
~匹配正则表达式
~!不匹配正则表达式
关系运算符
<, <=, >, >=, ==, !=关系运算符

注,所有用算术运算符进行的操作,所有非数值类型操作数会自动变为0.

一些示例:

awk 'BEGIN{a=3**3;  print a}' #3的3次幂
---
27

awk 'BEGIN{a=3^3;  print a}' #3的3次幂
---
27

awk 'BEGIN{a=3^3; if(!(a==28))  print "yes"}' #逻辑非
---
yes

awk 'BEGIN{a="abcde"; if(a ~ /bc/) {print "yes"}}' #a是否匹配正则
---
yes

awk 'BEGIN{a="abc"; a += 3; print a}' #非数值类型进行算术运算时自动变为0
---
3

【语句】

语句类型语句描述
条件控制语句
if(condition)...else if(condition)...else
循环语句
while(condition) {语句}
for(变量 in 数组) {语句}
for(变量;condition;表达式) {语句}
do {语句} while(condition)
其它语句
break
continue
next读入下一行
exit{}中退出跳转到END,END中退出终止脚本

【函数】

函数类型函数描述使用示例
数学函数
atan2(y,x)反正切函数
cos(x)余弦函数
sin(x)正弦函数
exp(x)以自然对数e为底的指数函数
log(x)以自然对数e为底的对数函数
sqrt(x)平方根函数
rand()返回0到1的随机数值,不包含1awk 'BEGIN{srand(); print rand(), rand()}'
srand(seed)设置随机种子,空则默认使用当前时间为种子
字符串函数
sub(ere, repl, [in])将in中第一个匹配ere部分替换为repl,in省略是默认使用$0, 返回替换的次数echo "hello world, hello world" | awk '{sub(/ello/, "i"); print $0}'
gsub(ere, repl, [in])将in中所有匹配ere部分替换为repl,in省略是默认使用$0, 返回替换的次数echo "hello world, hello world" | awk '{print gsub(/ello/, "i", $0); print $0}'
index(s,t)返回字符串t在s中出现的位置,位置从1开始计算,如果没找到返回0awk 'BEGIN{print index("abcde", "cd")}'
length([s])返回字符串s的长度,如不指定s则默认使用$0echo "hello world" | awk '{print length()}'
match(s, ere)返回字符串s匹配ere的起始位置,如果不匹配则返回0,内置函数RSTART与返回值相同,RLENGTH返回匹配字符串的长度,如果不匹配在返回-1awk 'BEGIN{a="abcde"; print match(a, "de"), RSTART, RLENGTH }'
split(s, a[, [fs])将字符串以分隔符fs(为空则使用FS)分隔成多分,并保存到数组a中,存放的位置从1开始,返回分隔的个数awk 'BEGIN{a="abc,def,kfc";print split(a,b,","); for(i in b) {print b[i]}}'
sprintf(fmt, expr, expr,…)功能类似printf,知识不会讲结果输出,而是当做返回值返回awk 'BEGIN{print sprintf("%s is a good man, %d aggree", "jerry", 99)}'
substr(s, m, n)返回字符串s从位置m开始,长度为n的子字符串,其中位置从1开始计算awk 'BEGIN{a="abcde"; print substr(a, 3, 9)}'
tolower(s)将字符串s转为小写awk 'BEGIN{print tolower("aBCDe")}'
toupper(s)将字符串s转为大写awk 'BEGIN{print toupper("aBCDe")}'
I/O处理函数
system执行外部命令awk 'BEGIN{system("ls")}'
参考
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值