shell编程之awk

发布于:2022-12-31 ⋅ 阅读:(1123) ⋅ 点赞:(0)

什么是awk

awkLinux以及UNIX环境中现有的功能最强大的数据处理工具。简单地讲,awk是一种处理文本数据的编程语言。awk的设计使得它非常适合于处理由行和列组成的文本数据。而在Linux或者UNIX环境中,这种类型的数据是非常普遍的。

除此之外,awk 还是一种编程语言环境,它提供了正则表达式的匹配,流程控制,运算符,表达式,变 量以及函数等一系列的程序设计语言所具备的特性。它从C语言中获取了一些优秀的思想。awk程序可以 读取文本文件,对数据进行排序,对其中的数值执行计算以及生成报表等。

awk的工作流程

awk命令的基本语法如下:

awk 'pattern { actions }'

在上面的语法中,pattern表示匹配模式,actions表示要执行的操作。以上语法表示,当某个文本行符合pattern指定的匹配规则时,执行actions所执行的操作。在上面的语法中,patternactions都是可选的,但是两者必须保证至少有一个。如果省略匹配模式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-scriptawk脚本文件名称,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

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到