awk命令的用法&商品脚本

awk命令的用法

AWK 是一种处理文本文件的语言,是一个强大的文本分析工具。
之所以叫 AWK 是因为其取了三位创始人 Alfred Aho,Peter Weinberger, 和 Brian Kernighan 的 Family Name 的首字符。

语法

awk [选项参数] 'script' var=value file(s)
或
awk [选项参数] -f scriptfile var=value file(s)

awk脚本
关于 awk 脚本,我们需要注意两个关键词 BEGIN 和 END。

BEGIN{ 这里面放的是执行前的语句 }
END {这里面放的是处理完所有的行后要执行的语句 }
{这里面放的是处理每一行时要执行的语句}

实例:

[root@wxy ~]#  awk 'BEGIN{print "姓名\t\t年龄\nyaya\t\t20\nhuanhuan\t19\njackson\t\t25\nwahaha\t\t18"}'
姓名            年龄
yaya            20
huanhuan        19
jackson         25
wahaha          18

打印年龄
[root@wxy ~]# awk '{print $2}' ww
年龄
20
19
25
18
[root@wxy ~]# echo|awk 'BEGIN{print "姓名\t\t年龄\nyaya\t\t20\nhuanhuan\t19\njackson\t\t25\nwahaha\t\t18"}' |awk '{print $2}'
年龄
20
19
25
18

模式匹配
当awk读入一行时,它试图匹配脚本中的每个模式匹配规则。只有与一个特定的模式相匹配的输入行才能成为操作对象。如果没有指定操作,与模式相匹配的输入行将被打印出来(执行打印语句是一个默认操作)。

[root@wxy ~]# vim awkscript
[root@wxy ~]# cat awkscript 
/[0-9]+/{print "这是一个数字"}
/[a-zA-Z]+/{print "这是一个字符串"}
/^$/{print "这是一个空行"}
[root@wxy ~]# awk -f awkscript 
2
这是一个数字
w
这是一个字符串
 
这是一个空行
ctrl+d 退出

程序脚本的注释

在写脚本时添加注释是一个好的习惯。注释以字符“#”开始,以换行符结束。和sed不同,awk 允许在程序的任何地方添加注释。
注意:如果以命令行的方式提供 awk程序,而不是将它写入一个文件中,那么在程序的任何地方都不能用单引号,否则shell将对它进行解释而导致错误。当我们开始编写叫本事,我们将用注释来对脚本进行描述:

# blank. awk -- Print message for each blank line.广$/ { print "This is a blank line." ]

注释指出了脚本的名字是blank.awk,并简洁的描述了脚本的功能。对于较长的脚本,注释可以用来描述输入文件的预期的结构。例如,在下一节,我们将学习编写脚本来读取包含姓名和电话号码的文件。这个程序的介绍性注释如下:
# blodklist.awk-打印表格中的名字和地址。
#字段:名字、公司、街道、城市、州和邮编、电话
将这些信息嵌入在程序脚本中是很有用的,因此除非输入文件的结构和所编写的程序脚本中的结构一直,否则将无法工作。

记录和字段
awk假设它的输入是有结构的,而不只是一串无规则的字符。在最简单的情况下,它将每个输入行作为一条记录,而将由空格或制表符(tab)分隔的单词作为字段(用来分隔字段的字符被称为分隔符,默认的分隔符就是空格,并且不管有多少个空格,它都会合并成一个)。
字段和引用的分离
awk允许使用字段操作符$来指定字段。在该操作符后面跟着一个数字或变量,用于标识字段的位置。“$1”表示第一个字段,“$2”表示第二个字段等等。“$0”表示整个输入记录。

1)正则内容
[root@wxy ~]# awk -F: '/^root/{print}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
2)~匹配,!~不匹配
[root@wxy ~]# awk -F: '$7!~/nologin/{print}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
wxy:x:1000:1000:wxy:/home/wxy:/bin/bash
student01:x:1001:1001::/home/student01:/bin/bash
yy:x:1002:1002::/home/yy:/bin/bash
3==,!=,>=,<=,>,<等,输出第二行文本
[root@wxy ~]# awk 'NR==2{print}' /etc/passwd
bin:x:1:1:bin:/bin:/sbin/nologin
4&&逻辑与:期望多条件都成立
[root@wxy ~]#  awk -F: '$3>=0&&$3<=10{print $1,$3}' /etc/passwd
root 0
bin 1
daemon 2
adm 3
lp 4
sync 5
shutdown 6
halt 7
mail 8

/取出本机ip地址
[root@wxy ~]# ip a|grep 'inet '|grep -v '127.0.0.1'|awk -F'[ /]+' '{print $3}' 
192.168.235.135

下面这个正则表达式可以分段进行解释。“1?”表示出现零个或一个1;“(-I)?”表示在随后的位置上查找一个连字符或一个空格,或什么也没有;“(?”表示查找零个或一个左括号;反斜杠能够防止将“(”解释为用于分组的元字符;“[O-9]+”表示查找一个或多个数字;注意我们采用了简便的方法,仅指定一到多位数字,而不是精确地指定3位数字。在随后的位置,我们查找一个可选的右括号,接着查找一个空格或一个连字符,或什么也没有。然后用”[O~9]+”查找一到多位数字,随后跟一个连字符,最后跟一到多位数字。

[root@wxy ~]# cat test
707-724-0000
(707) 724-0000
(707)724-0000
1-707-724-0000
1 707-724-0000
1(707)724-0000

[root@wxy ~]# awk '/1?[- ]?\(?[0-9]+\)?[- ]?[0-9]+-[0-9]+/' test  
707-724-0000
(707) 724-0000
(707)724-0000
1-707-724-0000
1 707-724-0000
1(707)724-0000

/匹配(707) 724-0000,(707)724-0000 两行
[root@wxy ~]# awk '/^\([0-9]+\) ?[0-9]+-[0-9]+/' test 
(707) 724-0000
(707)724-0000
// "^"  开头

求平均成绩

[root@wxy ~]# cat score.awk 
#!/bin/awk -f
#运行前
BEGIN {
    math = 0
    english = 0
    computer = 0
 
    printf "NAME    NO.   MATH  ENGLISH  COMPUTER   TOTAL\n"
    printf "---------------------------------------------\n"
}
#运行中
{
    math+=$3
    english+=$4
    computer+=$5
    printf "%-6s %-6s %4d %8d %8d %8d\n", $1, $2, $3,$4,$5, $3+$4+$5
}
#运行后
END {
    printf "---------------------------------------------\n"
    printf "  TOTAL:%10d %8d %8d \n", math, english, computer
    printf "AVERAGE:%10.2f %8.2f %8.2f\n", math/NR, english/NR, computer/NR
}


[root@wxy ~]# awk -f score.awk score.txt
NAME    NO.   MATH  ENGLISH  COMPUTER   TOTAL
---------------------------------------------
Marry  2143     78       84       77      239
Jack   2321     66       78       45      189
Tom    2122     48       77       71      196
Mike   2537     87       97       95      279
Bob    2415     40       57       62      159
---------------------------------------------
  TOTAL:       319      393      350 
AVERAGE:     63.80    78.60    70.00

表达式
可以使用表达式来存储、操作和检索数据,这些操作与sed中的有很大的区别,但这是大多数程序设计语言所具有的共同特性。
一个表达式通过计算返回一个值。表达式由数字和字符串常量、变量、操作符、函数和正则表达式组成。
常量有两种类型:字符串型或数字型(“red”或1)。字符串在表达式中必须用引号括起来。

常用的转义序列:
\n 换行符
\t 水平制表符

变量是引用值的标识符。定义变量只需要为它定义一个名字并将数据赋给它即.可。变量名只能由字母、数字和下划线组成。而且不能以数字开头。变量名的大小写很重要: Salary 和salary是两个不同的变量,变量不必进行说明,你不必告诉awk什么类型的数据存储在一个变量中。每个变量有一个字符串型值和数字型值,awk能够根据表达式的前后关系来选择合适的值(不包含数字的字符串值为0)。变量不必初始化。awk 自动将它们初始化为空字符串,如果作为数字,它的值为0。

运算符

运算符描述
= += -= *= /= %= ^= **=赋值
?: C条件表达式
&&逻辑与
~ 和 !~匹配正则表达式和不匹配正则表达式
< <= > >= != ==关系运算符
空格连接
+ -加,减
* / %乘,除与求余
+ - !一元加,减和逻辑非
^ ***
++ –增加或减少,作为前缀或后缀
$ 字段引用
in数组成员

赋值操作符

操作符定义
++变量 加1
变量减1
+=将加的结果赋给变量
-+将减的结果赋给变量
*=将乘的结果赋给变量
/=将除的结果赋给变量
%=将取模的结果赋给变量
^=将取幂的结果赋给变量
**=将取幂的结果赋给变量

内建变量

变量描述
$n当前记录的第n个字段,字段间由FS分隔
$0完整的输入记录
ARGC命令行参数的数目
ARGIND命令行中当前文件的位置(从0开始算)
ARGV包含命令行参数的数组
CONVFMT数字转换格式(默认值为%.6g)ENVIRON环境变量关联数组
ERRNO最后一个系统错误的描述
FIELDWIDTHS字段宽度列表(用空格键分隔)
FILENAME当前文件名
FNR各文件分别计数的行号
FS字段分隔符(默认是任何空格)
IGNORECASE如果为真,则进行忽略大小写的匹配
NF一条记录的字段的数目
NR已经读出的记录数,就是行号,从1开始
OFMT数字的输出格式(默认值是%.6g)
OFS输出字段分隔符,默认值与输入字段分隔符一致。
ORS输出记录分隔符(默认值是一个换行符)
RLENGTH由match函数所匹配的字符串的长度
RS记录分隔符(默认是一个换行符)
RSTART由match函数所匹配的字符串的第一个位置
SUBSEP组下标分隔符(默认值是/034)

商品脚本

[root@wxy ~]# cat breakfast 
热干面 5
杂酱面 8
重庆小面 6
三鲜粉面 7
[root@wxy ~]# cat script.sh 
#!/bin/bash

echo "想吃点啥?我这儿有:"
awk   '{print NR"." $1,$2"元"}' breakfast

read -p "输入想购买的早餐:" choice
read -p "输入购买的数量:" num

awk -vcount=$num -vline=$choice 'NR==line{print "您买了"count"碗"$1,"花了"$2*count"元" }' breakfast

echo 帅哥美女明早又来哦!

运行脚本:
[root@wxy ~]# source script.sh 
想吃点啥?我这儿有:
1.热干面 52.杂酱面 83.重庆小面 64.三鲜粉面 7元
输入想购买的早餐:2   
输入购买的数量:4
您买了4碗杂酱面 花了32元
帅哥美女明早又来哦!

关系操作符和布尔操作符
关系操作符和布尔操作符用于在两个表达式之间进行比较。

操作符描述
<小于
>大于
<=小于或等于
>=大于或等于
==相等
!=不相等的
~匹配
!~不匹配
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值