awk基础

awk介绍,awk基本语法,直接使用action,打印列,初识列和行,\$0、\$NF、NF,基础示例,begin模式,end模式



awk介绍

awk其实是一门编程语言,它支持条件判断、数组、循环等功能。所以可以把awk理解成一个脚本语言解释器。
grep 、sed、awk被称为linux中的"三剑客"。
他们的特点:

grep 更适合单纯的查找或匹配文本
sed  更适合编辑匹配到的文本
awk  更适合格式化文本,对文本进行较复杂格式处理



awk基本语法

基本语法

awk [options] 'program' file1 , file2 , ```

对于上述语法中的program来说,又可以细分成pattern和action,也就是说,awk的基本语法如下

awk [options] 'Pattern{Action}' file

action指的就是动作,awk擅长文本格式化,并且将格式化以后的文本输出,所以awk最常用的动作就是print和printf.



直接使用action

先从最简单用法开始了解awk,先不使用[options] ,也不指定pattern,直接使用最简单的action,从而开始认识awk。

[root@node1 course]# echo zaishu>awktest
[root@node1 course]# awk '{print}' awktest 
zaishu



打印列

[root@node1 course]# df -h
Filesystem               Size  Used Avail Use% Mounted on
/dev/mapper/centos-root   48G  4.6G   44G  10% /
devtmpfs                 223M     0  223M   0% /dev
tmpfs                    235M     0  235M   0% /dev/shm
tmpfs                    235M  5.5M  229M   3% /run
tmpfs                    235M     0  235M   0% /sys/fs/cgroup
/dev/sda1                197M  125M   73M  64% /boot
tmpfs                     47M     0   47M   0% /run/user/0
[root@node1 course]# df -h | awk '{print $4}'
Avail
44G
223M
235M
229M
235M
73M
47M

上图中的awk ‘{print $4}’,表示输出df的信息的第4列,$4表示将当前行按照分隔符分割后的第4列,不指定分隔符时,默认使用空格作为分隔符,细心的你一定发现了,上述信息用的空格不止有一个,而是有连续多个空格,awk自动将连续的空格理解为一个分割符了。



初识列和行

awk是逐行处理的,逐行处理的意思就是说,当awk处理一个文本时,会一行一行进行处理,处理完当前行,再处理下一行,awk默认以"换行符"为标记,识别每一行,也就是说,awk跟我们人类一样,每次遇到"回车换行",就认为是当前行的结束,新的一行的开始,awk会按照用户指定的分割符去分割当前行,如果没有指定分割符,默认使用空格作为分隔符。

(一)awk基础_mysql



$0、$NF、NF

$0和$NF均为内置变量;$0 表示显示整行;$NF表示当前行分割后的最后一列
注意,$NF 和 NF 要表达的意思是不一样的,对于awk来说,$NF表示最后一个字段,NF表示当前行被分隔符切开以后,一共有几个字段。

awk自动将连续的空格理解为一个分割符了,如果没有指定分割符,默认使用空格作为分隔符。
假如一行文本被空格分成了7段,那么NF的值就是7,$NF的值就是$7, 而$7表示当前行的第7个字段,也就是最后一列,那么每行的倒数第二列可以写为$(NF-1)。



基础示例

[root@node1 course]# cat awktxt 
zaishu	mysql	qq
xasdf	xxx	sdfsadf
dd	xx
sadf	sdfsad
sadfdsaf	sadfsadf	sdfsa	dfd
可以一次输出多个列

打印多列

[root@node1 course]# awk '{print $2,$3,$4}'  awktxt
mysql qq 
xxx sdfsadf 
xx  
sdfsad  
sadfsadf sdfsa dfd
多行没有对应的列,所以并没有输出任何文本,而第五行有第所有列,所以输出了。

添加字段作为列的内容

[root@node1 course]# awk '{print $2,$3,"test"}'  awktxt
mysql qq test
xxx sdfsadf test
xx  test
sdfsad  test
sadfsadf sdfsa test
[root@node1 course]# awk '{print "1fr:"$1,"3th:"$3}'  awktxt
1fr:zaishu 3th:qq
1fr:xasdf 3th:sdfsadf
1fr:dd 3th:
1fr:sadf 3th:
1fr:sadfdsaf 3th:sdfsa

$引用列时,不能加"",否则当成普通字符串

[root@node1 course]# awk '{print $1}' awktxt 
zaishu
xasdf
dd
sadf
sadfdsaf
[root@node1 course]# awk '{print "$1"}' awktxt 
$1
$1
$1
$1
$1
[root@node1 course]# awk '{print "1fi:"$1}' awktxt 
1fi:zaishu
1fi:xasdf
1fi:dd
1fi:sadf
1fi:sadfdsaf
[root@node1 course]# awk '{print "1fi:$1"}' awktxt 
1fi:$1
1fi:$1
1fi:$1
1fi:$1
1fi:$1

整行输出
使用$0或者不使用$

[root@node1 course]# awk '{print}' awktxt 
zaishu	mysql	qq
xasdf	xxx	sdfsadf
dd	xx
sadf	sdfsad
sadfdsaf	sadfsadf	sdfsa	dfd
[root@node1 course]# awk '{print $0}' awktxt 
zaishu	mysql	qq
xasdf	xxx	sdfsadf
dd	xx
sadf	sdfsad
sadfdsaf	sadfsadf	sdfsa	dfd



初识模式(begin end)

awk的语法如下

awk [options] 'Pattern{Action}' file

awk是逐行处理的, 刚才已经说过了最常用的Action,就是print打印。
现在认识下一Pattern,也就是模式。详解介绍模式之前(模式篇幅很长),先介绍两个容易入门理解的特殊模式BEGIN和END。

BEGIN 模式指定了处理文本之前需要执行的操作
END 模式指定了处理完所有行之后所需要执行的操作

示例
在开始处理文件中的文本之前,先执行打印动作,输出的内容为"aaa",“bbb”.

[root@node1 course]# cat awktxt 
zaishu	mysql	qq
xasdf	xxx	sdfsadf
dd	xx
sadf	sdfsad
sadfdsaf	sadfsadf	sdfsa	dfd
[root@node1 course]# awk 'BEGIN{print "aaa","bbb"}' awktxt 
aaa bbb

没有给定任何输入来源,awk就直接输出信息了,因为,BEGIN模式表示,在处理指定的文本之前,需要先执行BEGIN模式中指定的动作,而上述示例没有给定任何输入源,但是awk还是会先执行BEGIN模式指定的"打印"动作,打印完成后,发现并没有文本可以处理,于是就只完成了"打印 aaa bbb"的操作。

这个时候,如果我们想要awk先执行BEGIN模式指定的动作,再根据执我们自定义的动作去操作文本,该怎么办呢?示例如下

[root@node1 course]# awk 'BEGIN{print "aaa","bbb"} {print $1,$2}'  awktxt
aaa bbb
zaishu mysql
xasdf xxx
dd xx
sadf sdfsad
sadfdsaf sadfsadf

BEGIN模式的作用就是,在开始逐行处理文本之前,先执行BEGIN模式所指定的动作。以此类推,END模式的作用就一目了然了,举例如下。

[root@node1 course]# awk '{print $1,$2} END{print "end1","end2"}'  awktxt
zaishu mysql
xasdf xxx
dd xx
sadf sdfsad
sadfdsaf sadfsadf
end1 end2

可以结合BEGIN模式和END模式一起使用。示例如下

[root@node1 course]# awk 'BEGIN{print "aaa","bbb"} {print $1,$2}  END{print "end1","end2"}'  awktxt
aaa bbb
zaishu mysql
xasdf xxx
dd xx
sadf sdfsad
sadfdsaf sadfsadf
end1 end2