『忘了再学』Shell基础 — 28、AWK中条件表达式说明 - 繁华似锦Fighting
source link: https://www.cnblogs.com/liuyuelinfighting/p/16358538.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
1、AWK的条件表达
如下图所示:
2、条件表达式说明
以下练习使用如下文本:
ID Name Python Linux MySQL Java 1 Tangs 88 87 86 85.55 2 Sunwk 99 98 97 96,66 3 Zhubj 77 76 75 74.44 4 Shahs 66 65 64 63.33
(1)BEGIN
BEGIN
是AWK的保留字,是一种特殊的条件类型。
BEGIN
的执行时机是在AWK程序一开始时,尚未读取任何数据之前执行。
BEGIN
后的动作只执行一次,因为当AWK开始从文件中读入数据,BEGIN
的条件就不再成立,所以BEGIN
定义的动作只能被执行一次。
练习:执行命令查看BEGIN
作用:
执行命令:awk 'BEGIN{print "This is BEGIN action"} {printf $2 "\t" $3 "\t" $6 "\t" "\n"}' student.txt
[root@localhost tmp]# awk 'BEGIN{print "This is BEGIN action"} {printf $2 "\t" $3 "\t" $6 "\t" "\n"}' student.txt This is BEGIN action Name Python Java Tangs 88 85.55 Sunwk 99 96.66 Zhubj 77 74.44 Shahs 66 63.33
- AWK命令只要检测不到完整的单引号不会执行,所以这个命令的换行不用加入
\
,就是一行命令- 上边命令定义了两个动作:
第一个动作使用BEGIN
条件,所以会在读入文件数据前打印“This is BEGIN action”(只会执行一次)
第二个动作会打印文件中的对应文本。
(2)END
END
也是AWK保留字,不过刚好和BEGIN
相反。
END
是在AWK程序处理完所有数据,即将结束时执行。END
后的动作只在程序结束时执行一次。
练习:执行命令查看END
作用:
执行命令:awk 'END{print "This is END action"} {printf $2 "\t" $3 "\t" $6 "\t" "\n"}' student.txt
[root@localhost tmp]# awk 'END{print "This is END action"} {printf $2 "\t" $3 "\t" $6 "\t" "\n"}' student.txt Name Python Java Tangs 88 85.55 Sunwk 99 96.66 Zhubj 77 74.44 Shahs 66 63.33 This is END action
说明:在输出结尾输入“This is END action”,这并不是文档本身的内容,而且只会执行一次。
(3)关系运算符
假设我想看看Java绩大于等于80分的学员是谁,就可以这样输入命令:
grep -v "Name" student.txt | awk '$6>=80 {printf $2 "\n"}'
# 判断第六字段(Java成绩)大于等于80分的行,如果判断式成立,则打印第2列(学员名) [root@localhost tmp]# grep -v "Name" student.txt | awk '$6>=80 {printf $2 "\n"}' Tangs Sunwk
grep -v "Name" student.txt
是把标题过滤掉。
(4)说明AWK中条件表达式的执行过程
要先说明一下,虽然AWK是列提取命令,但是也要按行来读入的。
在AWK处理一个文本文件的时候:
- 先判断表达式中有没有
BEGIN
。
如果有,就先执行BEGIN
定义的操作,且执行一次。 - 如果没有
BEGIN
或者BEGIN
定义的动作执行完成之后,会把文本中的第一行数据读入AWK中,
把该行的整行数据赋予$0
变量中,
把该行数据的第一列赋值在$1
变量中,第二列赋值在$2
变量中,以此类推。 - 例如
awk '{printf $2 "\n"}' student.txt
,意思是打印文本中的第二列姓名。
我们先忽略掉条件,流程是:
AWK读取第一行数据(上面一步),然后执行动作输出第二列信息,也就是输出第一行的第二列信息。
然后开始读取第二行数据,然后再执行动作,输出第二行的第二列信息,
然后再读取第三行数据,之后执行动作,输出第三行的第二列信息,
以此类推,基本上就是这样的一个过程。 - 然后在加上条件
awk '$6>=80 {printf $2 "\n"}' student.txt
判断第六列Java的成绩大于80分,才输出。
还是和上边一样,先是AWK读取第一行数据完成之后,就要处理动作了,
但是在处理动作之前,先要判断一下动作前面的条件是否成立,
如果成立,则执行后边的动作。
如果不成立,则不执行跟在后边的动作。
然后在开始读取第二行数据,重复上边的流程,以此类推。
总结一下就是:加入了条件之后,只有条件成立动作才会执行,如果条件不满足,则动作则不运行。 - 最后如果有
END
,则把END
中定义的动作执行一次。
以上就是AWK的执行流程。
(5)AWK中使用正则表达式
如果要想让AWK识别字符串,必须使用//
包含,//
中识别的就是正则表达式规则匹配的字符串。
# 输出打印Sunwk的成绩 # awk会匹配有Sunwk符号的行,并输出 [root@localhost tmp]# awk '/Sunwk/ {print}' student.txt 2 Sunwk 99 98 97 96.66
注意:这里要注意在AWK中,使用
//
包含的字符串,AWK命令才会查找。也就是说字符串必须用//
包含,AWK命令才能正确识别。
(6)A~B
练习
A~B
是A包含B的意思。
练习:查看Sunwk
用户的Java成绩。
# 匹配第二字段中包含有“Sun”字符,则打印第六字段数据 [root@localhost tmp]# awk '$2 ~ /Sun/ {printf $6 "\n" }' student.txt 96.66
提示:(6)练习的方式,是在某一列中查找是否包含一个字符串。而上面(5)的写法,是在一行数据当中匹配是否包含一个字符串,根据需求灵活使用。
注意:
~
两边有无空格都可以。
拓展练习:
当使用df
命令查看分区使用情况时,如果我只想查看真正的系统分区的使用状况,而不想查看光盘和临时分区的使用状况,则可以执行如下:
# 查询包含有sda+数字的行,并打印第一字段和第五字段 [root@localhost tmp]# df -h | awk '/sda[0-9]/ {printf $1 "\t" $5 "\t" "\n"}' /dev/sda3 12% /dev/sda1 15%
__EOF__
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK