什么是awk
awk是Linux以及UNIX环境中现有的功能最强大的数据处理工具。简单地讲,awk是一种处理文本数据的编程语言。awk的设计使得它非常适合于处理由行和列组成的文本数据。而在Linux或者UNIX环境中,这种类型的数据是非常普遍的。
除此之外,awk 还是一种编程语言环境,它提供了正则表达式的匹配,流程控制,运算符,表达式,变 量以及函数等一系列的程序设计语言所具备的特性。它从C语言中获取了一些优秀的思想。awk程序可以 读取文本文件,对数据进行排序,对其中的数值执行计算以及生成报表等。
awk的工作流程
awk命令的基本语法如下:
awk 'pattern { actions }'
在上面的语法中,pattern表示匹配模式,actions表示要执行的操作。以上语法表示,当某个文本行符合pattern指定的匹配规则时,执行actions所执行的操作。在上面的语法中,pattern和actions都是可选的,但是两者必须保证至少有一个。如果省略匹配模式pattern,则表示对所有的文本行执行actions所表示的操作;如果省略actions,则表示将匹配成功的行输出到屏幕。
对于初学者来说,搞清楚awk的工作流程非常重要。只有在掌握了awk的工作流程之后,才有可能用好
awk来处理数据。在awk处理数据时,它会反复执行以下4个步骤:
(1)自动从指定的数据文件中读取行文本。
(2)自动更新awk的内置系统变量的值,例如列数变量NF、行数变量NR、行变量$0以及各个列变量 $1、$2等等
(3)依次执行程序中所有的匹配模式及其操作。
(4)当执行完程序中所有的匹配模式及其操作之后,如果数据文件中仍然还有未读取的数据行,则返回到第(1)步,重复执行(1)~ (4)操作
awk程序的执行方式
1.通过命令行执行awk程序,语法如下:
awk 'program-text' datafile
2.执行awk脚本
在awk程序语句比较多的情况下,用户可以将所有的语句写在一个脚本文件中,然后通过awk命令来解释并执行其中的语句。awk调用脚本的语法如下:
awk -f program-file file ..
在上面的语法中,-f选项表示从脚本文件中读取awk程序语句,program-file表示awk脚本文件名称,file表示要处理的数据文件。
3. 可执行脚本文件
在上面介绍的两种方式中,用户都需要输入awk命令才能执行程序。除此之外,用户还可以通过类似于Shell脚本的方式来执行awk程序。在这种方式中,需要在awk程序中指定命令解释器,并且赋予脚本文件的可执行权限。其中指定命令解释器的语法如下:
#!/bin/awk -f
以上语句必须位于脚本文件的第一行。然后用户就可以通过以下命令执行awk程序:
awk-script file
其中,awk-script为awk脚本文件名称,file为要处理的文本数据文件。
awk打印一个内容和打印多个内容,
格式化输出:显示Hello World字符串且宽度为50,向左对齐
[root@r8 ~]# cat file1
hellow world
[root@r8 ~]# awk '{printf "%-50s",$0}' file1
hellow world [root@r8 ~]#
awk的变量
(1)内置变量
变量 | 说明 |
$0 | 记录变量,表示当前正在处理的记录 |
$n |
字段变量,其中 n 为整数,且 n 大于 1 。表示第 n 个字段的值
|
NF |
整数值,表示当前记录(变量 $0 所代表的记录)的字段数
|
NR |
整数值,表示 awk 已经读入的记录数;如果有多个文件,这个数目会把处理的多个文件中行统一计数。(显示的是文件的每一行的行号)
|
FNR |
与 NR 不同的是, FNR 用于记录正处理的行是当前这一文件中被总共处理的行数;
|
FILENAME |
表示正在处理的数据文件的名称
|
FS |
输入字段分隔符,默认值是空格或者制表符,可使用 -F 指定分隔符
|
OFS |
输出字段分隔符 , OFS=”#” 指定输出分割符为 # 。
|
RS |
记录分隔符,默认值是换行符\n
|
ENVIRON |
当前 shell 环境变量及其值的关联数组;
|
[root@r8 ~]# echo "1:2:3:4" | awk -F : '{print $3}'
3
[root@r8 ~]# awk '{print NR}' file1
1
2
3
4
5
6
[root@r8 ~]# awk '{print NF}' file1
3
3
3
3
3
0
[root@r8 ~]# awk '{print FNR}' file1
1
2
3
4
5
6
[root@r8 ~]# echo "1:2:3:4" | awk -F : '{print $0}'
1:2:3:4
[root@r8 ~]# echo "1:2:3" | awk 'BEGIN{FS=":";FS="-"}{print $0,$1,$2}'
1:2:3 1:2:3
[root@r8 ~]# awk 'BEGIN {OFS="#"} {print $1,$2}' file1
hellow#world
[root@r8 ~]# awk 'BEGIN{print ENVIRON["PATH"]}'
/usr/local/python3.8/Python-3.8.1/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
(2)用户自定义变量
awk允许用户自定义自己的变量以便在程序代码中使用,变量名命名规则与大多数编程语言相同,只能使用字母、数字和下划线,且不能以数字开头。awk变量名称区分字符大小写。
1.
在awk中给变量赋值使用赋值语句进行
[root@r8 ~]# awk 'BEGIN{test="hellow";printf test}'
hellow[root@r8 ~]#
2.
在命令行中使用赋值变量
awk命令也可以在“脚本”外为变量赋值,并在脚本中进行引用。例如,上述的例子还可以改写为:
[root@r8 ~]# awk -v test="hellow" 'BEGIN {print test}'
hellow
awk执行数学计算: 10/2*3+5%2+2^3
[root@r8 ~]# awk 'BEGIN{print 10/2*3+5%2+2^3}'
24
awk处理文本:要求文本有5行内容,且当行数为奇数的时候打印第一个字段
[root@r8 ~]# awk '{if (NR%2==1 && "END{print NR}==5") print $1}' file1
hellow
hellow
hellow
awk处理文本: 要求文本有5行内容, 当行数不为3时打印第一个字段
[root@r8 ~]# awk '{if (NR!=3 && "END{print NR}==5") print $1}' file1
hellow
hellow
hellow
hellow
awk处理文本:文本内容为ls -l /root的内容,匹配所有的普通文件的文件名
[root@r8 ~]# ll > file2
[root@r8 ~]# awk '/^-/' file2
-rw-r--r--. 1 root root 2 Aug 16 18:22 2
-rw-------. 1 root root 1210 Apr 13 00:12 anaconda-ks.cfg
-rw-r--r--. 1 root root 11800498 Apr 27 21:10 Discuz_X3.4_SC_UTF8_20191201.zip
-rw-r--r-- 1 root root 76 Sep 2 05:20 file1
-rw-r--r-- 1 root root 0 Sep 3 04:24 file2
-rw-r--r--. 1 root root 1482 Apr 13 00:23 initial-setup-
awk中控制语句
if: 给定一个成绩0-100,输出等级: A:85-100, B:70-84, C:60-69, D:0-59
[root@r8 ~]# cat score.txt
120
30
56
75
95
81
[root@r8 ~]# cat awk_1.sh
#!/bin/awk -f
{
if ($1 >= 85 && $1 <= 100){
print $1,"A"
}
else
{
if ($1 >= 70 && $1<=84){
print $1,"B"
}
else
{
if ($1 >= 60 && $1 <=69){
print $1,"C"
}
else
{
if ($1 >=0 && $1 <= 59){
print $1,"D"
}
else
{
print $1 " Tips:value 0-100"
}
}
}
}
}
[root@r8 ~]# chmod a+x awk_if.sh
[root@r8 ~]# ./awk_if.sh score.txt
120 Tips:value 0-100
30 D
56 D
75 B
95 A
81 B
for(): 计算1+2…+100的和
[root@r8 shell_ex]# vim awk_for.sh
#!/bin/awk -f
BEGIN{
sum=0
for(i=1;i<=100;i++){
sum+=i
}
print sum
}
[root@r8 shell_ex]# ./awk_for.sh
5050
for(in): 定义一个数组:数组中的元素为:
array[name]=age,-> zhangsan:18 lisi:20 wangwu=21
循环访问数组,并输出数组中的key和value
[root@r8 shell_ex]# vim awk_array.sh
#!/bin/awk -f
BEGIN{
array["zhangsan"]=18
array["lisi"]=20
array["wangwu"]=21
for(var in array){
print var,array[var]
}
}
[root@r8 shell_ex]# ./awk_array.sh
zhangsan 18
wangwu 21
lisi 20
用while实现9*9乘法表
[root@r8 shell_ex]# vim while_awk.sh
#!/bin/awk -f
BEGIN{
j=1
while (i<=9){
while (j<=i){
t=i*j
printf("%d*%d=%d\t",i,j,t)
j++
}
i++
j=1
printf("\n")
}
}
[root@r8 shell_ex]# chmod a+x while_awk.sh
[root@r8 shell_ex]# ./while_awk.sh
1*1=1
2*1=2 2*2=4
3*1=3 3*2=6 3*3=9
4*1=4 4*2=8 4*3=12 4*4=16
5*1=5 5*2=10 5*3=15 5*4=20 5*5=25
6*1=6 6*2=12 6*3=18 6*4=24 6*5=30 6*6=36
7*1=7 7*2=14 7*3=21 7*4=28 7*5=35 7*6=42 7*7=49
8*1=8 8*2=16 8*3=24 8*4=32 8*5=40 8*6=48 8*7=56 8*8=64
9*1=9 9*2=18 9*3=27 9*4=36 9*5=45 9*6=54 9*7=63 9*8=72 9*9=81
awk中内置函数的使用:substr, tolower, toupper, system
功能:取string字符串中的子串,从start开始,取length个;start从1开始计数;
[root@r8 shell_ex]# awk 'BEGIN{print substr("uplooking",u,2)}'
up
功能:将s中的所有字母转为小写
[root@r8 shell_ex]# awk 'BEGIN{print tolower("WWW.BAIDU.COM")}'
www.baidu.com
功能:将s中的所有字母转为大写
[root@r8 shell_ex]# awk 'BEGIN{print toupper("www.baidu.com")}'
WWW.BAIDU.COM
功能:执行系统command并将结果返回至awk命令
[root@r8 shell_ex]# awk 'BEGIN{print system("whoami")}'
root
0