awk ‘条件 1{动作 1} 条件 2{动作 2}…’ 文件名
条件(Pattern):
一般使用关系表达式作为条件。这些关系表达式非常多,具体参考表 12-3 所示,例如:
x > 10 判断变量 x 是否大于 10
x == y 判断变量 x 是否等于变量 y
A ~ B 判断字符串 A 中是否包含能匹配 B 表达式的子字符串
A !~ B 判断字符串 A 中是否不包含能匹配 B 表达式的子字符串
动作(Action):
格式化输出
流程控制语句
执行流程
1) 如果有 BEGIN 条件,则先执行 BEGIN 定义的动作
2) 如果没有 BEGIN 条件,则读入第一行,把第一行的数据依次赋予1、
0
代表此行的整体数据,2 代表第二字段。
2) 依据条件类型判断动作是否执行。如果条件符合,则执行动作,否则读入下一行数据。如果
没有条件,则每行都执行动作。
3) 读入下一行数据,重复执行以上步骤
[root@localhost ~]# awk '{printf $2 "\t" $6 "\n"}' student.txt
#输出第二列和第六列
begin
[root@localhost ~]# awk 'BEGIN{printf "This is a transcript \n" }
{printf $2 "\t" $6 "\n"}' student.txt
#awk 命令只要检测不到完整的单引号不会执行,所以这个命令的换行不用加入“\”,就是一行命令
#这里定义了两个动作
#第一个动作使用 BEGIN 条件,所以会在读入文件数据前打印“这是一张成绩单”(只会执行一次)
end
[root@localhost ~]# awk 'END{printf "The End \n" }
{printf $2 "\t" $6 "\n"}' student.txt
#在输出结尾输入“The End”,这并不是文档本身的内容,而且只会执行一次
关系运算符
[root@localhost ~]# cat student.txt | grep -v Name | \
awk '$6 >= 87 {printf $2 "\n" }'
#使用 cat 输出文件内容,用 grep 取反包含“Name”的行
#判断第六字段(平均成绩)大于等于 87 分的行,如果判断式成立,则打第六列(学员名)
包含
[root@localhost ~]# awk '$2 ~ /Sc/ {printf $6 "\n"}' student.txt
#如果第二字段中输入包含有“Sc”字符,则打印第六字段数据
85.66
正则
[root@localhost ~]# awk '/Liming/ {print}' student.txt
#打印 Liming 的成绩
[root@localhost ~]# df -h | awk '/sda[0-9]/ {printf $1 "\t" $5 "\n"} '
#查询包含有 sda 数字的行,并打印第一字段和第五字段
指定分隔符
[root@localhost ~]# cat /etc/passwd | grep "/bin/bash" | \
awk 'BEGIN {FS=":"} {printf $1 "\t" $3 "\n"}'
流程控制
在 awk 编程中,因为命令语句非常长,在输入格式时需要注意以下内容:
多个条件{动作}可以用空格分割,也可以用回车分割。
在一个动作中,如果需要执行多个命令,需要用“;”分割,或用回车分割。
在 awk 中,变量的赋值与调用都不需要加入“$”符。
条件中判断两个值是否相同,请使用“==”,以便和变量赋值进行区分。
[root@localhost ~]# awk 'NR==2{php1=$3}
NR==3{php2=$3}
NR==4{php3=$3;totle=php1+php2+php3;print "totle php is " totle}' student.txt
#统计 PHP 成绩的总分
function 函数名(参数列表){
函数体
}
awk 'function test(a,b) { printf a "\t" b "\n" }
{ test($2,$6) } ' student.txt
awk 中调用脚本
[root@localhost ~]# vi pass.awk
BEGIN {FS=":"}
{ print $1 "\t" $3}
awk -f pass.awk /etc/passwd
root 0
bin 1
daemon 2
网友评论