shell脚本三剑客之awk命令

awk:

创新互联从2013年成立,先为横山等服务建站,横山等地企业,进行企业商务咨询服务。为横山企业网站制作PC+手机+微官网三网同步一站式服务解决您的所有建站问题。

测试用模版:

M.Tansley 05/99 48311 Green   8  40 44.44

J.Lulu    06/99 48317 green   9  24 2678.

P.Bunnyaaa   02/99 48    Yellow  12 35 2658

J.Troll   07/99 4842  Brown-3 12 26 266666

L.Tansleyaaa 05/99 4712  Brown-2 12 30 44544

模式和动作:

  最常用的动作是打印(print)也有较长的动作代码if和while和for,

  模式可以是任何条件语句或复合语句或正则表达式也包括两个特殊字段BEGIN和END。

BEGIN的使用是在awk正式对文本做读取操作之前,END则是在awk在做完所有操作之后

awk脚本的输入方法:

脚本名(test.awk) 文件名(abc.txt)正规使用方法为方法一

方法一:test.awk abc.txt

方法二:test.awk < abc.txt

方法三:abc.txt | test.awk

awk使用时出现错误的原因:

确保整个awk命令用单引号括起来。

确保命令内所有引号成对出现。

确保用花括号括起动作语句,用圆括号括起条件语句。

可能忘记使用花括号,也许你认为没有必要,但awk不这样认为,将按之解释语法。

NR:表示awk开始执行程序后所读取的数据行数

例:[root@localhost awk]# awk '{print NR}' data.f     

1

2

3

4

5

释:也可以在花括号前加入END字段,表示打印最后一行行数。

$NF:最后一列数据

例:[root@localhost awk]# awk '{print $NF}' data.f    

44.44

2678.

2658

266666

44544

释:可以在花括号前加入END,表示打印最后一行的最后一列。

保存输出:

例:[root@localhost awk]# awk '{print $0}' data.f |tee wow

M.Tansley 05/99 48311 Green   8  40 44.44

J.Lulu    06/99 48317 green   9  24 2678.

P.Bunnyaaa   02/99 48    Yellow  12 35 2658

J.Troll   07/99 4842  Brown-3 12 26 266666

L.Tansleyaaa 05/99 4712  Brown-2 12 30 44544

释:"$0"打印全行,tee是将管道符前面的结果保存到wow文件中同时标准输出在屏幕上。

打印报告头和结束尾:

例:[root@localhost awk]# awk 'BEGIN {print "name     color\n------------------------"} {print $1,$4}' data.f     

name     color

------------------------

M.Tansley Green

J.Lulu green

P.Bunnyaaa Yellow

J.Troll Brown-3

L.Tansleyaaa Brown-2

释:”\n“另起一行

例:[root@localhost awk]# awk 'BEGIN {print "name     color\n---------------"} {print $1,$4} END {print "\n-----------jieshu"}' data.f 

name     color

--------------------

M.Tansley Green

J.Lulu green

P.Bunnyaaa Yellow

J.Troll Brown-3

L.Tansleyaaa Brown-2

---------------jieshu

[root@localhost awk]# awk 'BEGIN {print "name\tcolor"} {print $1"\t" $2}' data.f    

name    color

M.Tansley       05/99

J.Lulu  06/99

P.Bunnyaaa      02/99

J.Troll 07/99

L.Tansleyaaa    05/99

释:”\t“执行tab键

正则表达式:

在awk中正则表达式是使用斜线来表示的,例如,查找Green字符可以这样表达"/Green/",在awk中可以使用的元字符有如下;

\ :转意符号,如果在命令中有特殊符号,但是不想用特殊符号的功能只需要在特殊符号前加转义符号。

. :一位任意数

[] :为查询大小写信息.

() :使用条件语句需要用圆括号。

* :多位任意数。

^ :匹配模式头部分

$ :匹配模式尾部分

| :或

? :匹配可能出现的字符

+ :使用+匹配一个或多个字符

条件操作符:

> :小于

例:[root@localhost awk]# awk '$3 < "48" {print $0}' data.f 

L.Tansleyaaa 05/99 4712  Brown-2 12 30 44544

例:[root@localhost awk]# awk '{if($6 > $7) print $1 "\tok"}' data.f.bak 

J.Troll ok

<= :小于等于

例:[root@localhost awk]# awk '$3 <= "48" {print $0}' data.f 

P.Bunnyaaa   02/99 48    Yellow  12 35 2658

L.Tansleyaaa 05/99 4712  Brown-2 12 30 44544

== :等于

例:[root@localhost awk]# awk '$3 == "48" {print $0}' data.f 

P.Bunnyaaa   02/99 48    Yellow  12 35 2658

!= :不等于

例:[root@localhost awk]# awk '$3 != "48" {print $0}' data.f 

M.Tansley 05/99 48311 Green   8  40 44.44

J.Lulu    06/99 48317 green   9  24 2678.

J.Troll   07/99 4842  Brown-3 12 26 266666

L.Tansleyaaa 05/99 4712  Brown-2 12 30 44544

例:[root@localhost awk]# awk '$0 !~ /Brown/' data.f 

M.Tansley 05/99 48311 Green   8  40 44.44

J.Lulu    06/99 48317 green   9  24 2678.

P.Bunnyaaa   02/99 48    Yellow  12 35 2658

>= :大于等于

例:[root@localhost awk]# awk '$3 >= "48" {print $0}' data.f 

M.Tansley 05/99 48311 Green   8  40 44.44

J.Lulu    06/99 48317 green   9  24 2678.

P.Bunnyaaa   02/99 48    Yellow  12 35 2658

J.Troll   07/99 4842  Brown-3 12 26 266666

~ :匹配正则表达式

例:[root@localhost awk]# awk '{if ($4~/Brown/) print $0}' data.f 

J.Troll   07/99 4842  Brown-3 12 26 266666

L.Tansleyaaa 05/99 4712  Brown-2 12 30 44544

例:[root@localhost awk]# awk '$0 ~/Brown/' data.f 

J.Troll   07/99 4842  Brown-3 12 26 266666

L.Tansleyaaa 05/99 4712  Brown-2 12 30 44544

!~ :不匹配正则表达式

例:[root@localhost awk]# awk '$0 !~/Brown/' data.f 

M.Tansley 05/99 48311 Green   8  40 44.44

J.Lulu    06/99 48317 green   9  24 2678.

P.Bunnyaaa   02/99 48    Yellow  12 35 2658

例:[root@localhost awk]# awk '{if ($4 !~/Brown/) print $0}' data.f 

M.Tansley 05/99 48311 Green   8  40 44.44

J.Lulu    06/99 48317 green   9  24 2678.

P.Bunnyaaa   02/99 48    Yellow  12 35 2658

任意字符匹配:

例:[root@localhost awk]# awk '$0~/^...a/ ' data.f

M.Tansley 05/99 48311 Green   8  40 44.44

L.Tansleyaaa 05/99 4712  Brown-2 12 30 44544

释:匹配开头前三位是任意字符第四位是a的字段。

“或”的使用:

例:[root@localhost awk]# awk '$0 ~ /(Brown|gree)/' data.f

J.Lulu    06/99 48317 green   9  24 2678.

J.Troll   07/99 4842  Brown-3 12 26 266666

L.Tansleyaaa 05/99 4712  Brown-2 12 30 44544

例;[root@localhost awk]# awk '$0 ~ /(Brown|[Gg]ree)/' data.f

M.Tansley 05/99 48311 Green   8  40 44.44

J.Lulu    06/99 48317 green   9  24 2678.

J.Troll   07/99 4842  Brown-3 12 26 266666

L.Tansleyaaa 05/99 4712  Brown-2 12 30 44544

行首:

例:[root@localhost awk]# awk '/^J/' data.f

J.Lulu    06/99 48317 green   9  24 2678.

J.Troll   07/99 4842  Brown-3 12 26 266666

符合模式:

&& :两边的是都为真,才能打印信息。(只针对一行有效)

例[root@localhost awk]# awk '{if ($3~/48/ && $4~/[Gg]reen/) print $0}' data.f

M.Tansley 05/99 48311 Green   8  40 44.44

J.Lulu    06/99 48317 green   9  24 2678.

|| :一边为真或全部为真

例:[root@localhost awk]# awk '{if ($0~/Brown/ || $4~/[Gg]reen/) print $0}' data.f

M.Tansley 05/99 48311 Green   8  40 44.44

J.Lulu    06/99 48317 green   9  24 2678.

J.Troll   07/99 4842  Brown-3 12 26 266666

L.Tansleyaaa 05/99 4712  Brown-2 12 30 44544

awk内置变量:

NR:文件行数

NF:域块个数

FILENAME:所指定的文件名

例:[root@localhost awk]# awk '{print NR,NF,$0} END{print FILENAME}' data.f

1 7 M.Tansley 05/99 48311 Green   8  40 44.44

2 7 J.Lulu    06/99 48317 green   9  24 2678.

3 7 P.Bunnyaaa   02/99 48    Yellow  12 35 2658

4 7 J.Troll   07/99 4842  Brown-3 12 26 266666

5 7 L.Tansleyaaa 05/99 4712  Brown-2 12 30 44544

data.f

例:[root@localhost awk]# echo $PWD |awk -F"/" '{print $NF}' 

awk

设置输入域到域变量名:

例:[root@localhost awk]# awk '{name=$1;color=$4;if(color~/Ye/) print name "\tok"}' data.f

P.Bunnyaaa      ok

释:注意分号的使用,它分隔 awk命令。

为变量赋值:

例:[root@localhost awk]# awk '{if ($6 < "27") print $0}' data.f

J.Lulu    06/99 48317 green   9  24 2678.

J.Troll   07/99 4842  Brown-3 12 26 266666

例:[root@localhost awk]#  awk 'BEGIN{shuzi="27 "} {if ($6 < shuzi) print $0}' data.f

J.Lulu    06/99 48317 green   9  24 2678.

J.Troll   07/99 4842  Brown-3 12 26 266666

释:通常在BEGIN部分赋值是很有益的,可以在awk表达式进行改动时减少很多麻烦。

修改数值域取值:

例:[root@localhost awk]# awk '{if ($1=="M.Tansley") $6=$6-1;print $1,$6,$7}' data.f

M.Tansley 39 44.44

J.Lulu 24 2678.

P.Bunnyaaa 35 2658

J.Troll 26 266666

L.Tansleyaaa 30 44544

释:M.Tansley从原来的40下降到39。

例:[root@localhost awk]# awk '{if ($1==$1) $6=$6-1;print $1,$6,$7}' data.f

M.Tansley 39 44.44

J.Lulu 23 2678.

P.Bunnyaaa 34 2658

J.Troll 25 266666

L.Tansleyaaa 29 44544

释:所有数字都减一。

修改文本域:

例:[root@localhost awk]# awk '{if ($1=="P.Bunnyaaa") ($1="P.Bunnyaaa.abcaaa");print $1}' data.f

M.Tansley

J.Lulu

P.Bunnyaaa.abcaaa

J.Troll

L.Tansleyaaa

释:记住字符串要使用双秒号( " ")不要忘记分号(;) ,并用圆括号括起整个语法。

只显示修改记录:

例:[root@localhost awk]# awk '{if ($1=="M.Tansley") {$1="M.Tansley.abc";print $1}}' data.f

M.Tansley.abc

例:[root@localhost awk]# awk '{if ($1=="M.Tansley") {$1="M.Tansley.abc";print $0}}' data.f

M.Tansley.abc 05/99 48311 Green 8 40 44.44

释:注意花括号的位置

创建新的输出域:

例:[root@localhost awk]# awk 'BEGIN{print "name\t fenzhi"} {if ($5 < $6) {$8=$6-$5;print $1,$8}}' data.f

name     fenzhi

M.Tansley 32

J.Lulu 15

P.Bunnyaaa 23

J.Troll 14

L.Tansleyaaa 18

释:在输出结果前打印一个头,然后在比较数值,“$8=$6-$5”这是在为$8赋值。记住使用语法的格式。

例:[root@localhost awk]# awk 'BEGIN{print "name \t shuzi"} {if ($5 < $6);diff=$6-$5;print $1,diff}' data.f

name     shuzi

M.Tansley 32

J.Lulu 15

P.Bunnyaaa 23

J.Troll 14

L.Tansleyaaa -90

释:也可以使用域变量名。

文件长度相加:

例:[root@localhost awk]# ll -h |awk '/^[^d]/ {print $8"\t"$5} {tol+=$5} END{print "zongshu:" tol}' 

data.f  217

data.f.bak      201

zongshu:422

释:数值相加的总和有偏差,应该是单位换算导致的结果有误。具体后期查一下。

替换(gsub):

例:[root@localhost awk]# awk 'gsub (/Green/,"abcd") {print $0}' data.f

M.Tansley 05/99 48311 abcd   8  40 44.44

释:整个记录中替换一个字符串为另一个,使用正则表达式格式, /目标模式/,替换模式

awk简单脚本:

例:[root@localhost awk]# cat jiaoben 

#!/bin/awk -f

#

BEGIN{

print "hello"

print "chengjiruxia"

print "===================================="

}

(tot+=$6)

END{print "zongshu:" tot

print "pingjunshu" tot/NR}

释:要给awk脚本加权限chmod u+x jiaoben ,不能这样使用sh jiaoben data.f。

释:tot/NR是tot总数除以行数(NR)

例:[root@localhost awk]# ./jiaoben data.f

hello

chengjiruxia

====================================

M.Tansley 05/99 48311 Green   8  40 44.44

J.Lulu    06/99 48317 green   9  24 2678.

P.Bunnyaaa   02/99 48    Yellow  12 35 2658

J.Troll   07/99 4842  Brown-3 12 26 266666

L.Tansleyaaa 05/99 4712  Brown-2 120 30 44544

zongshu:155

pingjunshu31

例:[root@localhost awk]# awk 'BEGIN{OFS=":"}{print $1,$3,$4}' digresult.txt 

news.sina.com.cn:111.12.251.212:111.12.251.203

jupiter.sina.com.cn:111.12.251.217:111.12.251.212

cmnetnews.sina.com.cn:111.12.251.219:111.12.251.217

us.sina.com.cn:111.12.251.212:111.12.251.203

www.sina.com:111.12.251.212:111.12.251.203

释:将打印的结果已冒号分隔又叫输出分隔符


新闻名称:shell脚本三剑客之awk命令
分享地址:http://pwwzsj.com/article/ijodio.html