10分钟精通ask shell编程

不特殊说明的情况下,awk 都指的是 gawk

gawk is a pattern scanning and processing language.
By default it reads standard input and writes standard output

FILENAME        当前输入文件名
FNR                 当前文件中的记录号
FS                    输入域分隔符,默认为一个空格
RS                   输入记录分隔符
NF                   当前记录里域个数
NR                  到目前为止记录数
OFS                 输出域分隔符
ORS                输出记录分隔符

awk 语法格式

awk '{pattern + action}' {filenames}

awk 版本的 helloworld 

[root@localhost data]# vim data
[root@localhost data]# cat data
hello world 
[root@localhost data]# awk '{print $1}' data
hello
#上面的命令等同于下面的
[root@localhost data]# cat data|awk '{print $1}'
hello
#怎么是 hello呢,world哪去了,难道是..
[root@localhost data]# awk '{print $1 $2}' data
helloworld
这下hello world出来了,但是和data中不一样的啊 
[root@localhost data]# awk '{print $1 "\t" $2}' data
hello	world

这下就差不多了把

怎样完整的输出内容呢,要一样样的

[root@localhost data]# awk '{ print }' data

上面这些都是从文件中读取 版本 的helloworld

现在再写一个 没有file 的helloworld

[root@localhost data]# awk '{ print $0 }'
hello world
hello world
#上面这个命令中,$0 代表输入的一行字符..所以你输入什么,系统就会打印什么
[root@localhost data]# awk '{ print }'
#经试验,这俩个的结果是一样的.

awk 之 格式化输出

[root@localhost data]# awk '{ printf("%s %s %.2f\n",$1,$2,$3*$1) }' data 


awk中的NF

awk中的NF用来表示当前行中(1行)有多少个字符

怎么理解呢,请看下面的 试验:

[root@localhost data]# cat 1.txt 
1
2	2
3	3	3
4	4	4	44

[root@localhost data]# awk 'NF >3 { print }' 1.txt 
4	4	4	44
[root@localhost data]# awk 'NF >4 { print }' 1.txt 

 awk 中的NR,NR为awk执行到的当前的行数

awk之BEGIN END

[root@localhost data]# cat awk.data 
Beth    4.00    0
Dan     3.75    0
Kathy   4.00    10
Mark    5.00    20
Mary    5.50    22
Susie   4.25    18
#命令中的print ""是打印1个空行,而print是打印当前输入行的内容
[root@localhost data]# awk 'BEGIN { print "Name    RATE    HOURS"; print ""} {print}' awk.data 
Name    RATE    HOURS

Beth    4.00    0
Dan     3.75    0
Kathy   4.00    10
Mark    5.00    20
Mary    5.50    22
Susie   4.25    18


awk 计数

[root@localhost data]# awk '$3>5 { emp = emp + 1 } END { print emp,"employees worked more than 15 hours" }' awk.data 
4 employees worked more than 15 hours

awk 中用不着去声明,直接使用就可以了


awk 求和与平均值,这里要用到awk中的一个内置变量,NR,表示到当前位置读取的行数

#读取当前文件中有多少行
[root@localhost data]# awk 'END { print NR}' awk.data 
6
求 awk.data 中员工的平均薪水
[root@localhost data]# awk '{ pay = pay + $2*$3 } { print NR "employees\n","total pay is ",pay,"\n","avg is ",pay/NR}' awk.data 
1employees
 total pay is  0 
 avg is  0
2employees
 total pay is  0 
 avg is  0
3employees
 total pay is  40 
 avg is  13.3333
4employees
 total pay is  140 
 avg is  35
5employees
 total pay is  261 
 avg is  52.2
6employees
 total pay is  337.5 
 avg is  56.25
[root@localhost data]# awk '{ pay = pay + $2*$3 } END { print NR "employees\n","total pay is ",pay,"\n","avg is ",pay/NR}' awk.data 
6employees
 total pay is  337.5 
 avg is  56.25

另一个版本


[root@localhost data]# awk ' $3 > 6 { n = n +1 ;pay = pay + $2 * $3 } END { if(n>0) print n,"ren,avg is ",pay/n ; else print "no one" }' awk.data 
4 ren,avg is  84.375



awk-寻找最高薪资的人
[root@localhost data]# awk ' $2 > maxrate  { maxrate = $2; maxname = $1 } END { printf("max salary is %s,the salary is %.2f\n",maxname,maxrate) }' awk.data 
max salary is Mary,the salary is 5.50

#千万注意不要写成下面这样,错误的原因 自己找
[root@localhost data]# awk '{ $2 > maxrate } { maxrate = $2; maxname = $1 } END { printf("max salary is %s,the salary is %.2f\n",maxname,maxrate) }' awk.data 
max salary is Susie,the salary is 4.25



awk 字符串拼接
[root@localhost data]# awk '{ name = name $1 "\r\n" } END { print name}' awk.data 
Beth
Dan
Kathy
Mark
Mary
Susie
[root@localhost data]# awk '{ name = name $1 " " } END { print name}' awk.data 
Beth Dan Kathy Mark Mary Susie



再体会下END 的作用
[root@localhost data]# awk '{ name = name $1 "\r\n" } END { print name}' awk.data 
Beth
Dan
Kathy
Mark
Mary
Susie

[root@localhost data]# awk '{ name = name $1 "\r\n"} { print name}' awk.data 
Beth

Beth
Dan

Beth
Dan
Kathy

Beth
Dan
Kathy
Mark

Beth
Dan
Kathy
Mark
Mary

Beth
Dan
Kathy
Mark
Mary
Susie



awk-length



[root@localhost data]# awk '{ print length("4.00");exit }' awk.data 
4
[root@localhost data]# awk '{ print length(4.00);exit }' awk.data 
1
[root@localhost data]# awk '{ print length(400000);exit }' awk.data 
6

[root@localhost data]# awk '{ nc = nc + length($0)+1 } {nw = nw + NF ;print nc ;} END { print NR,"lines",nw,"words",nc,"counts" }' awk.data 
18
36
55
74
93
112
#可能你想明明第一行就只有个 "Beth    4.00    0" 怎就18呢..这里面其实把tab制表符的长度也算进去了.另外换行也+1


awk-条件判断-if else


[root@localhost data]# awk ' $2 > 6 { n = n +1 ;pay = pay + $2 * $3 } END { if(n>0) print n,"ren,avg is ",pay/n ; else print "no one" }' awk.data


awk-条件判断——awk 复利计算器

while 版本

[root@localhost data]# vim rate
# rate - 计算复利
#   输入: 钱数    利率    年数
#   输出: 复利值
{   i = 1
    while (i <= $3) {
        printf("\t%.2f\n", $1 * (1 + $2) ^ i)
        i = i + 1
    }
}
:wq!  [root@localhost data]# awk -f rate 
1000 0.05 3
 1050.00
 1102.50
 1157.63
1000 0.06 2
 1060.00
 1123.60


#for循环的实例
#依次输入:投资金额 年化率 年数
#这个实例明显比上一个while 实例要好理解的多
{
 for( i=1;i <= $3 ;i = i+1 ){
  printf("\t第%d年,利息有%.2f,\t本息%.2f\n",i,$1*$2,$1*(1+$2)^i );
 }
}

[root@localhost data]# awk -f forrate 
10000 0.08 10
 第1年,利息有800.00,	本息10800.00
 第2年,利息有800.00,	本息11664.00
 第3年,利息有800.00,	本息12597.12
 第4年,利息有800.00,	本息13604.89
 第5年,利息有800.00,	本息14693.28
 第6年,利息有800.00,	本息15868.74
 第7年,利息有800.00,	本息17138.24
 第8年,利息有800.00,	本息18509.30
 第9年,利息有800.00,	本息19990.05
 第10年,利息有800.00,	本息21589.25
#10000万元的本金,8%的年化率,寸10年就翻倍了.

[root@localhost data]# awk -f forrate 
1000000 0.08 20
 第1年,利息有80000.00,	本息1080000.00
 第2年,利息有80000.00,	本息1166400.00
 第3年,利息有80000.00,	本息1259712.00
 第4年,利息有80000.00,	本息1360488.96
 第5年,利息有80000.00,	本息1469328.08
 第6年,利息有80000.00,	本息1586874.32
 第7年,利息有80000.00,	本息1713824.27
 第8年,利息有80000.00,	本息1850930.21
 第9年,利息有80000.00,	本息1999004.63
 第10年,利息有80000.00,	本息2158925.00
 第11年,利息有80000.00,	本息2331639.00
 第12年,利息有80000.00,	本息2518170.12
 第13年,利息有80000.00,	本息2719623.73
 第14年,利息有80000.00,	本息2937193.62
 第15年,利息有80000.00,	本息3172169.11
 第16年,利息有80000.00,	本息3425942.64
 第17年,利息有80000.00,	本息3700018.05
 第18年,利息有80000.00,	本息3996019.50
 第19年,利息有80000.00,	本息4315701.06
 第20年,利息有80000.00,	本息4660957.14
#赶紧学习好技能赚钱,100万存4年 4倍啊...得写多少代码才能挣那么多啊

do-while

[root@localhost data]# cat do_awk 
#do-while
{
i=1

do{
	printf("\t第%d年,利息有%.2f,\t本息%.2f\n",i,$1*$2,$1*(1+$2)^i );
   i = i + 1;
}while(i<=$3)

}
[root@localhost data]# awk -f do_awk 
10000 0.06 10
	第1年,利息有600.00,	本息10600.00
	第2年,利息有600.00,	本息11236.00
	第3年,利息有600.00,	本息11910.16
	第4年,利息有600.00,	本息12624.77
	第5年,利息有600.00,	本息13382.26
	第6年,利息有600.00,	本息14185.19
	第7年,利息有600.00,	本息15036.30
	第8年,利息有600.00,	本息15938.48
	第9年,利息有600.00,	本息16894.79
	第10年,利息有600.00,	本息17908.48




awk 中的数组 Array

[root@localhost data]# vim awk_array 
[root@localhost data]# cat awk_array 
#awk 中 array的用法,用起来就和JavaScript中的array一样
{
 #忘记有没有说$0的意思,$0就是当前行的内容
 #NR就是当前行号,从1开始 
 line[NR] = $0 
}

END 
{ i = NR;
  while (i > 0) {
     print line[i];
     i = i - 1;
  }
}

[root@localhost data]# awk -f awk_array awk.data 
Susie   4.25    18
Mary    5.50    22
Mark    5.00    20
Kathy   4.00    10
Dan     3.75    0
Beth    4.00    0




小提示,awk中0作为 除号 后面的数 的处理

[root@localhost data]# awk '$1 %2 == 0 {print $2}' data 
name2
name0
[root@localhost data]# awk '$1 /2 == 0 {print $2}' data 
name0
[root@localhost data]# cat data 
1	name1
2	name2
0	name0



精通了吧,哈哈哈

你可能感兴趣的:(10分钟精通ask shell编程)