【总结】Shell三剑客之AWK

本文深入讲解了AWK命令的基础语法、工作流程、变量使用、操作符、模式匹配、控制语句及内置函数等内容,帮助读者全面掌握AWK的使用技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

awk基本语法

awk命令的基本语法如下:

awk ‘pattern { actions }’

在上面的语法中,pattern表示匹配模式,actions表示要执行的操作。以上语法表示,当某个文本行符合pattern指定的匹配规则时,执行actions所执行的操作。在上面的语法中,pattern和actions都是可选的,但是两者必须保证至少有一个。如果省略匹配模式pattern,则表示对所有的文本行执行actions所表示的操作;如果省略actions,则表示将匹配成功的行输出到屏幕。

awk的工作流程

在awk处理数据时,它会反复执行以下4个步骤:

  1. 自动从指定的数据文件中读取行文本。
  2. 自动更新awk的内置系统变量的值,例如列数变量NF、行数变量NR、行变量$0以及各个列变量$1、$2等等。
  3. 依次执行程序中所有的匹配模式及其操作。
  4. 当执行完程序中所有的匹配模式及其操作之后,如果数据文件中仍然还有未读取的数据行,则返回到第(1)步,重复执行(1)~(4)的操作。

awk程序的执行方式

  1. 通过命令行执行awk程序,语法如下:

awk ‘program-text’ datafile

  1. 执行awk脚本
    在awk程序语句比较多的情况下,用户可以将所有的语句写在一个脚本文件中,然后通过awk命令来解释并执行其中的语句。awk调用脚本的语法如下;在下面的语法中,-f选项表示从脚本文件中读取awk程序语句,program-file表示awk脚本 文件名称,file表示要处理的数据文件。

awk -f program-file file …

  1. 可执行脚本文件
    在上面介绍的两种方式中,用户都需要输入awk命令才能执行程序。除此之外,用户还可以通过类似于Shell脚本的方式来执行awk程序。在这种方式中,需要在awk程序中指定命令解释器,并且赋予脚本文件的可执行权限。其中指定命令解释器的语法如下:

#!/bin/awk -f
以上语句必须位于脚本文件的第一行。然后用户就可以通过以下命令执行awk程序:

awk-script file
其中,awk-script为awk脚本文件名称,file为要处理的文本数据文件。

测试用例:

  • awk打印一个内容和打印多个内容,格式化输出:显示Hello World字符串且宽度为50,向左对齐
[root@haha day9]# more test_txt 
a s d f 
1 2 3 4 
l o i u 
1 3 5 l v g 
[root@haha day9]# awk 'BEGIN{printf"%-30s\n","Hello World",OFS="-"}{print $1,$2}' test_txt
Hello World                   
a-s
1-2
l-o
1-3
[root@haha day9]# more awk_script 
BEGIN{printf "%-30s","Hello world"}
{
print $1,$3
}
END{
print"-------END------"
}

[root@haha day9]# more awk_x 
#!/bin/awk -f
BEGIN{print "-----BEGIN-----",OFS="-"}
{
print $1 ,$3
}
END{
print"-----END-----"
}
[root@haha day9]# awk -f awk_script test_txt 
Hello world                   a d
1 3
l i
1 5
-------END------
[root@haha day9]# ./awk_x test_txt 
-----BEGIN-------
a-d
1-3
l-i
1-5
-----END-----

awk的变量

  • awk内置变量
变量说明
$0记录变量,表示当前正在处理的记录
$n字段变量,其中n为整数,且n大于1。表示第n个字段的值
NF整数值,表示当前记录(变量$0所代表的记录)的字段数
NR整数值,表示awk已经读入的记录数;如果有多个文件,这个数目会把处理的多个文件中行统一计数。(显示的是文件的每一行的行号)
FNR与NR不同的是,FNR用于记录正处理的行是当前这一文件中被总共处理的行数;
FILENAME表示正在处理的数据文件的名称
FS输入字段分隔符,默认值是空格或者制表符,可使用-F指定分隔符
OFS输出字段分隔符 ,OFS=”#”指定输出分割符为#。
RS记录分隔符,默认值是换行符 \n
ENVIRON当前shell环境变量及其值的关联数组;
  • 用户自定义变量
    awk允许用户自定义自己的变量以便在程序代码中使用,变量名命名规则与大多数编程语言相同,只
    能使用字母、数字和下划线,且不能以数字开头。awk变量名称区分字符大小写。
    在awk中给变量赋值使用赋值语句进行
    示例:
awk 'BEGIN{test="hello";print test}' hello

在命令行中使用赋值变量
awk命令也可以在“脚本”外为变量赋值,并在脚本中进行引用。例如,上述的例子还可以改写为:

 awk -v test="hello" 'BEGIN {print test}' hello

内置变量的使用

[root@haha day9] awk 'BEGIN{OFS="-";FS=" "}{print $1,$0,NF,NR,FNR,FILENAME,RS,ENVIRON["PATH"]}' test_txt
a-a s d f -4-1-1-test_txt-
-/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/usr/java/jdk1.8.0_60//bin:/root/bin
1-1 2 3 4 -4-2-2-test_txt-
-/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/usr/java/jdk1.8.0_60//bin:/root/bin
l-l o i u -4-3-3-test_txt-
-/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/usr/java/jdk1.8.0_60//bin:/root/bin
1-1 3 5 l v g -6-4-4-test_txt-
-/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/usr/java/jdk1.8.0_60//bin:/root/bin

awk操作符

awk是一种编程语言环境,因此,它也支持常用的运算符以及表达式,例如算术运算、逻辑运算以及关
系运算等。

运算符说明举例
+加法运算1+1表示计算1和1的和
-减法运算12-2表示计算12和2的差
*乘法运算2*10表示计算2和10的积
/除法运算6/2表示计算6和2的商
%求模运算5%2表示计算5除以2的余数
^指数运算2^3表示计算2的3次方

实例:

[root@haha day9] awk 'BEGIN{print 10/2*3+5%2+2^3 }'
24
  • 赋值运算符
运算符说明举例
=赋值运算x=5表示将数值5赋给变量x
+=复合赋值运算表示将前后两个数值相加后的和赋给前面的变量x+=5表示先将x的值与5相加,然后再将和赋给变量x,等价于x=x+5
-=复合赋值运算,表示将前后两个数值相减后的值赋给前面的变量x-=5表示先将x的值减去5,然后再将得到的差赋给变量x,等价于x=x-5
*=复合赋值运算,表示前后两个数的乘积赋给前面的变量x*=5表示先将x的值乘以5,然后再将得到的乘积赋给变量x
/=复合赋值运算,表示前后两个数值的商赋给前面的变量表示先将变量x除以5,再将商赋给变量x
%=复合赋值运算,表示将前面的数值除以后面的数值所得的余数赋给前面的变量将变量x与5相除后的余数赋给变量x
^=复合运算符,表示将前面的数值的后面数值次方赋给前面的变量x^=3表示将变量x的3次方赋给变量x

awk的模式

  • 关系表达式
    awk提供了许多关系运算符,例如大于>、小于<或者等于==等。awk允许用户使用关系表达式作为匹
    配模式,当某个文本行满足关系表达式时,将会执行相应的操作。

  • 正则表达式
    awk支持以正则表达式作为匹配模式,与sed一样,用户需要将正则表达式放在两条斜线之间,其基本语
    法如下:/regular_expression/

  • 混合模式
    awk不仅支持单个的关系表达式或者正则表达式作为模式,还支持使用逻辑运算符&&、||或者!将多个表达式组合起来作为一个模式。其中,&&表示逻辑与,||表示逻辑或,!表示逻辑非。

  • 区间模式
    awk还支持一种区间模式,也就是说通过模式可以匹配一段连续的文本行。区间模式的语法如下:
    pattern1, pattern2
    其中,pattern1和pattern2都是前面所讲的匹配模式,可以是关系表达式,也可以是正则表达式等。当然,也可以是这些模式的混合形式。

  • BEGIN模式
    BEGIN模式是一种特殊的内置模式,其成立的时机为awk程序刚开始执行,但是又尚未读取任何数据之前。因此,该模式所对应的操作仅仅被执行一次,当awk读取数据之后,BEGIN模式便不再成立。所以,用户可以将与数据文件无关,而且在整个程序的生命周期中,只需执行1次的代码放在BEGIN模式对应的操作中。

  • END模式
    END模式是awk的另外一种特殊模式,该模式成立的时机与BEGIN模式恰好相反,它是在awk命令处理完所有的数据,即将退出程序时成立,在此之前,END模式并不成立。无论数据文件中包含多少行数据,在整个程序的生命周期中,该模式所对应的操作只被执行1次。因此,一般情况下,用户可以将许多善后工作放在END模式对应的操作中。

实例:

[root@haha day9] awk 'BEGIN{print"-----BEGIN-----"}/^a/&&$2==2{print $0}END{print "-----END-----"}' test_txt 
-----BEGIN-----
a 2 2 2 
-----END-----

awk控制语句

作为一种程序设计语言,awk支持程序的流程控制,例如条件判断、循环以及其他的一些流程控制语
句,例如continue、break以及exit等。掌握这些基本的流程控制语句,对于编写出结构良好的程序非常
重要。
实例:

[root@haha day9] more awk_fa 
BEGIN{
num=0
for(i=1;i<=100;i++){num+=i}
print num
}
END{}
[root@haha day9] awk -f awk_fa test_txt 
5050
[root@haha day9] more awk_ach 
BEGIN{OFS="-"}
{
if($2>=85){print "the ach of",$1, "is A"} else
if($2>=70){print "the ach of",$1, "is B"} else
if($2>=60){print "the ach of",$1, "is C"} else
if($2>=0){print "the ach of",$1, "is D"}
}
[root@haha day9] more class_ach.txt 
lc 100
ls 70
ly 60
lk 0
[root@haha day9] awk -f awk_ach class_ach.txt 
the ach of-lc-is A
the ach of-ls-is B
the ach of-ly-is C
the ach of-lk-is D
[root@haha day9] more awk_99 
BEGIN{
	for(j=1;j<=9;j++){
	i=1
	while(i<=j){
	printf i"*"j"=" i*j"  " 
	i++
	}
printf"\n"
}
}
[root@haha day9] awk -f awk_99 
1*1=1  
1*2=2  2*2=4  
1*3=3  2*3=6  3*3=9  
1*4=4  2*4=8  3*4=12  4*4=16  
1*5=5  2*5=10  3*5=15  4*5=20  5*5=25  
1*6=6  2*6=12  3*6=18  4*6=24  5*6=30  6*6=36  
1*7=7  2*7=14  3*7=21  4*7=28  5*7=35  6*7=42  7*7=49  
1*8=8  2*8=16  3*8=24  4*8=32  5*8=40  6*8=48  7*8=56  8*8=64  
1*9=9  2*9=18  3*9=27  4*9=36  5*9=45  6*9=54  7*9=63  8*9=72  9*9=81  

awk数组

index-expression可以使用任意字符串;需要注意的是,如果某数组元素事先不存在,那么在引用 时,awk会自动创建此元素并初始化为空串;因此,要判断某数组中是否存在某元素,需要使用index in array的方式。

[root@haha day9] more awk_array 
BEGIN{
array["zhangsan"]="18"
array["lisi"]="20"
array["wangwu"]="21"
print array["zhangsan"]
print array["lisi"]
print array["wangwu"]
for(i in array){
	print i,array[i]
}
}
[root@haha day9] awk -f awk_array 
18
20
21
zhangsan 18
wangwu 21
lisi 20

awk内置函数

函数名作用
split(string, array [, fieldsep [, seps ] ])功能:将string表示的字符串以fieldsep为分隔符进行分隔,并将分隔后的结果保存至array为名的数组中;数组下标为从1开始的序列;
length([string])功能:返回string字符串中字符的个数;
substr(string, start [, length])功能:取string字符串中的子串,从start开始,取length个;start从1开始计数;
system(command)功能:执行系统command并将结果返回至awk命令
systime()功能:取系统当前时间
tolower(s)功能:将s中的所有字母转为小写
toupper(s)功能:将s中的所有字母转为大写

实例:

[root@haha day9] date +%T | awk '{split ($0,hehe,":");for(i in hehe){print hehe[i]}}'
14
51
30
[root@haha day9]# date +%T | awk '{a=length($0);print a}'
8
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值