shell脚本学习笔记九——awk
#cat grade.txt
M.Tansley 05/99 48311 Green 8 40 44
J.Lulu 06/99 48317 green 9 24 26
P.Bunny 02/99 48 Yellow 12 35 28
J.Troll 07/99 4842 Brown-3 12 26 26
L.Tansley 05/99 4712 Brown-2 12 30 28
awk '{print $1,$4}' grade.txt
打印报告头
awk 'BEGIN {print "Name \t Belt\n--------------------"}{print
$1"\t"$4}' grade.txt
打印信息尾
# awk 'BEGIN{print "Name \t \n------"}{print $1}END{print "--end of
report--"}' grade.txt
Name
------
M.Tansley
J.Lulu
P.Bunny
J.Troll
L.Tansley
--end of report--
awk中正则表达式及其操作
1) 元字符 \ ^ $ . [] | () * + ?
2) 条件操作符 < <= == != >= ~ 匹配正则表达式 !~ 不匹配正则
表达式
匹配 使一域号匹配正则表达式,使用 ‘~’后紧跟正则表达式,也可以使用
if语句.awk中if后面的条件用()括起来
# awk '{if($4 ~/Brown/)print $0}' grade.txt
J.Troll 07/99 4842 Brown-3 12 26 26
L.Tansley 05/99 4712 Brown-2 12 30 28
# awk '$0 ~/Brown/' grade.txt
J.Troll 07/99 4842 Brown-3 12 26 26
L.Tansley 05/99 4712 Brown-2 12 30 28
精确匹配
# awk '{if($3=="48") print $0}' grade.txt 第三列有很多
48,所以要用精确匹配
P.Bunny 02/99 48 Yellow 12 35 28
# awk '$3==48' grade.txt awk默认动作是
print
P.Bunny 02/99 48 Yellow 12 35 28
awk '{ if ($6 < $7) print $1" Try better at..."}' grade.txt
M.Tansley Try better at...
J.Lulu Try better at...
设置大小写 [] 可匹配任意字符或单词
awk '{if($4 ~/[Gg]reen/) print $0}' grade.txt
M.Tansley 05/99 48311 Green 8 40 44
J.Lulu 06/99 48317 green 9 24 26
awk '/[Gg]reen/' grade.txt 结果同上
任意字符
[root@localhost awk_sed]# awk '$1 ~/^...a/' grade.txt
M.Tansley 05/99 48311 Green 8 40 44
L.Tansley 05/99 4712 Brown-2 12 30 28
awk '{if(/^...a/) print}' grade.txt 结果同上
或关系匹配 | 匹配两边模式之一 使用竖线符时,语句必须用圆括号
括起来
# awk '$4 ~/([Yy]ellow|[Bb]rown)/' grade.txt 抽取级别为yellow或
brown的记录
P.Bunny 02/99 48 Yellow 12 35 28
J.Troll 07/99 4842 Brown-3 12 26 26
L.Tansley 05/99 4712 Brown-2 12 30 28
行首
# awk '/^48/' grade.txt
# awk '/^P.B/' grade.txt
P.Bunny 02/99 48 Yellow 12 35 28
所有表达式(除字符重复出现外)在awk中都是合法的。
复合模式 && || !
# awk '{if($1=="P.Bunny" && $4=="Yellow") print $0}' grade.txt
P.Bunny 02/99 48 Yellow 12 35 28
awk '{if($4=="green" || $4 ~/Brown/) print $0}' grade.txt
J.Lulu 06/99 48317 green 9 24 26
J.Troll 07/99 4842 Brown-3 12 26 26
L.Tansley 05/99 4712 Brown-2 12 30 28
awk内置变量
ARGC 命令行参数个数
ARGV 命令行参数排列 ARGV[n]表示每一元素,n为期望访问的
命令行参数
ENVIRON 支持队列中系统环境变量的使用
FILENAME awk浏览的文件名 awk可以同时处理许多文件
FNR 浏览文件的记录数
FS 设置输入域分隔符,等价于命令行-F选项。如果用逗号作域分隔符
,设置 FS=","
NF 浏览记录的域个数
NR 已读的记录数
OFS 输出域分隔符 缺省为空格。若想设置为#,写入OFS="#"
ORS 输出记录分隔符 缺省为新行(\n)
RS 控制记录分隔符 缺省为新行(\n)
下面为awk内置变量的例子
NR 快速查看记录个数,比如导出数据库文件后,要快速浏览记录个数。
# awk 'END{print NR}' grade.txt
5
# awk '{print NR}' grade.txt
1
2
3
4
5
#awk '{print NF,NR,$0}END{print FILENAME}' grade.txt 打印所有学生的
记录,并打印记录号及域个数(NF),文件名
7 1 M.Tansley 05/99 48311 Green 8 40 44
7 2 J.Lulu 06/99 48317 green 9 24 26
7 3 P.Bunny 02/99 48 Yellow 12 35 28
7 4 J.Troll 07/99 4842 Brown-3 12 26 26
7 5 L.Tansley 05/99 4712 Brown-2 12 30 28
grade.txt
在抽取信息时,最好先检查文件中是否有记录。
# awk '{if(NR>0 && $4 ~/Brown/)print $0}' grade.txt
J.Troll 07/99 4842 Brown-3 12 26 26
L.Tansley 05/99 4712 Brown-2 12 30 28
NF 的一个强大功能是将变量$PWD的返回值传入awk并显示其目录。这里需要指
定域分隔符
# echo $PWD | awk -F/ '{print $NF}'
awk_sed
echo "/usr/local/src" | awk -F/ '{print $NF}' 显示文件名
src
awk操作符
在awk中使用操作符,基本表达式分为划分数字型,字符串型,变量型,域及
数组元素
= += *= 、 = %= ^= 赋值操作符
? 条件表达操作符
|| && ! 并,与,非
- !- 匹配操作符,包括匹配和不匹配
< <= == != >> 关系操作符
+ - * / % ^ 算术操作符
++ -- 前缀和后缀
1.设置输入域到域变量名
# awk '{name=$1;belts=$4; if(belts ~/Yellow/)print name"is belt"
belts'} grade.txt
P.Bunnyis beltYellow
2域值比较操作
两种方法:1.在BEGIN中给变量名赋值 2.在关系操作中使用实际数值。
用引号将数字引起来是可选的,“27”和27是一样的!
[root@localhost awk_sed]# awk '{if($6<27)print $0}' grade.txt
J.Lulu 06/99 48317 green 9 24 26
J.Troll 07/99 4842 Brown-3 12 26 26
# awk 'BEGIN {BASELINE="27"}{if($6<27) print $0}' grade.txt
J.Lulu 06/99 48317 green 9 24 26
J.Troll 07/99 4842 Brown-3 12 26 26
3. 修改数值域取值
awk修改任何域时,重要的一点是要记住实际输入文件是不可修改的,修改的
只是保存在缓存里的awk副本。awk会在变量NR或NF变量中反映出修改痕迹0。
awk '{if ($1=="M.Tansley") $6=$6-1;print $1 "\t" $6 "\t" $7}'
grade.txt
M.Tansley 39 44
J.Lulu 24 26
P.Bunny 35 28
J.Troll 26 26
L.Tansley 30 28
4. 修改文本域
awk '{if($1=="J.Troll") $1=="J.L.Troll";print $1}' grade.txt
M.Tansley
J.Lulu
P.Bunny
J.Troll
L.Tansley
5.只显示修改记录 在模式后面使用花括号将只打印修改部分
awk '{if($1=="J.Troll") {$1=="J.L.Troll";print $1}}' grade.txt
J.Troll
6.创建新的输出域