Linux shell编程自动化运维,三剑客之awk脚本编程 详细解析

awk 脚本编程

awk调用变量

自定义内部变量 -v

awk -v user=root -F: '$1 == user' /etc/passwd
-v定义变量

外部变量 " ’ '"

双引号
   # var="bash"
# echo "unix script" | awk "{print "123",\"$var\"}"
   123 bash
注意 awk调用外部变量时,外部使用双引号,内部也使用双引号,但需要转义内部的双引号
单引号
   # var="bash"
# echo "unix script" |awk '{print $1,"'"$var"'"}'
   unix  bash
注意使用单引号时,内部需要用双引转义

条件判断

if 语句

格式

{if(表达式){语句;语句;…}}

示例
如果$3是0,就说他是管理员

awk -F: '{if($3==0) {print $1 " is administrator."}}' /etc/passwd

if…else 语句

格式

{if(表达式){语句;语句;…}else{语句;语句;…}}
{if(){}else{}}

示例 1
如果第三列是0,打印该行第一列,否则法印第七列,登入shell

awk -F: '{if($3==0){print $1} else {print $7}}' /etc/passwd

示例 2
统计管理员和系统用户的数量

awk -F: '{if($3==0){count++} else{i++}} END{print "管理员个数: "count ; print "系统用户数: "i}' /etc/passwd

if…else if…else 语句

格式

{if(表达式1){语句;语句;…}else if(表达式2){语句;语句;…}else if(表达式3){语句;语句;…}else{语句;语句;…}}
==========================================================================
if (条件){动作}elseif(条件){动作}else{动作}
==========================================================================
if(){}else if (){}else if(){}else{}

示例 1
题目:显示出三种用户的信息
管理员:管理员ID为0
内置用户:用户ID<1000
普通用户: 用户ID>999

[root@localhost ~]# awk -F:  '{if($3==0){print $1," is admin "}else if ($3>999){print $1," is user"}else {print $1, " is sofo user"}}'  /etc/passwd

示例 2
题目:统计出三种用户的数量
管理员数量:管理员ID为0
内置用户数量:用户ID<1000
普通用户数量: 用户ID>999

awk -F: '{if($3==0){i++} else if($3>999){k++} else{j++}} END{print i; print k; print j}' /etc/passwd

升级脚本
awk -F: '{if($3==0){i++} else if($3>999){k++} else{j++}} END{print "管理员个数: "i; print "普通用个数: "k; print "系统用户: "j}' /etc/passwd

循环

while 循环
循环打印10个数字

awk 'BEGIN{  while(i<=10){print i; i++} }'

第一行打印十次

awk -F: '{ while(i<=9) {print $0; i++}}'  passwd

for 循环
循环打印5个数字

awk 'BEGIN{for(i=1;i<=5;i++){print i} }'

如果是用 {},和 END{} 的话需要有文件。


将每一行打印10次

awk -F: '{ for(i=1;i<=10;i++) {print $0} }' /etc/passwd

打印每一行的每一列

 awk -F: '{ for(i=1;i<=NF;i++) {print $i} }' passwd

数组

定义数组
将用户名定义为数组的值,打印第一个值

# awk -F: '{username[++i]=$1} END{print username[1]}' /etc/passwd
root

数组遍历
按索引遍历

[root@localhost ~]#  awk -F: '{username[x++]=$1} END{for(i in username) {print i,username[i]} }' /etc/passwd

awk 编程案例
统计1. 统计/etc/passwd中各种类型shell的数量

awk -F: '{shells[$NF]++} END{ for(i in shells){print i,shells[i]} }' /etc/passwd

提示

$NF 最后一列的字段内容
{}行处理
把统计的对象,作为索引。每次递增。
Print i 打印索引
Shells[i] 数组加索引,显示的就是值。

统计Apache/Nginx日志中的访问前十 <统计日志>

cat  access_log |awk '{ips[$1]++} END{for(i in ips){print i,ips[i]} }' |sort -k2 -rn |head



# awk  '/west/'  datafile
	匹配west
# awk  '/^north/'  datafile
	以north开头
# awk  '$3 ~ /^north/'  datafile
	第三列 匹配 north开头的
# awk  '/^(no|so)/'  datafile
	no或者so 开头
# awk  '{print $3,$2}'  datafile
	打印第23列,逗号引用分隔符。默认引用OFS=" "
# awk  '{print $3 $2}'  datafile
	打印第23列,没有分隔符
# awk  '{print $0}'  datafile
	打印记录,默认整行
# awk  'END {print "Number of fields: "NF}'  datafile 
	格式化文字“字段数”:列数
# awk  '/northeast/{print $3,$2}'  datafile
	匹配north行的第3,2列
# awk  '/E/'  datafile
	匹配包含E的所有行
# awk  '/^[ns]/{print $1}'  datafile
	以n或s开头行的第一列
# awk  '$5 ~ /\.[7-9]+/'  datafile
	第五列 匹配 .1到多个7,8,9的行
# awk  '$2 !~ /E/{print $1,$2}'  datafile
	第二列 中不包含E的行,打印第1,2列。
# awk  '$3 ~ /^Joel/{print $3 "  is a nice boy."}' datafile
	在第三列中匹配 以Joel开头的行,打印行中的第3列
# awk  '$8 ~ /[0-9][0-9]$/{print $8}'  datafile
	匹配第八列,两个数字结尾,打印第八列
# awk  '$4 ~ /Chin$/{print "The price is $" $8 "."}'  datafile
	在第四列中 匹配 Chin结尾的字段, 格式化文字加第八列带个点
# awk  '/Tj/{print $0}'  datafile
	匹配Tj的行
# awk -F:  '{print $1}'  /etc/passwd
	冒号分割打印第一列
# awk -F"[ :]"  '{print NF}'  /etc/passwd
	以冒号或空格作为字段分隔符 ,并打印列数
# awk -F"[ :]+"  '{print NF}'  /etc/passwd 
	以1到多个冒号或空格作为字段分隔符 ,并打印列数
# awk  '$7 == 5'  datafile
	打印第七列是5 的行
# awk  '$2 == "CT"  {print $1, $2}' datafile
	打印第二列是CT的行的第1,2列
# awk  '$7 != 5'  datafile
	打印第七列不等于5的行
# awk  '$7 < 5  {print $4, $7}' datafile
	打印第七列小于5的行
# awk  '$6 > .9 {print $1,$6}'  datafile
	打印第6列大于.9的行的第1,6列
# awk  '$8 <= 17 {print $8}'  datafile
	打印第八列小于等于17的行的第八列
# awk  '$8 >= 17 {print $8}'  datafile
	打印第八列大于等于17的行的第八列
# awk  '$8 > 10 && $8 < 17'  datafile
	第八列大于10,并小于17的行。
# awk  '$2 == "NW" || $1 ~ /south/ {print $1, $2}'  datafile
	第二列有NW,或者,第一列包含south的行,只打印第1,2列
# awk  '!($8 == 13){print $8}'  datafile
	第八列不等于13,打印匹配行的第八列($8!=13)
# awk -F":"  '/root/  {print $3 + 10}'  /etc/passwd
	匹配root字段,第三列+10并打印。
# awk  '/southem/{print $8 + 10}'  datafile
	匹配southerm,打印第八列+10
# awk  '/southem/{print $5 + 10.56}'  datafile
	匹配southerm,打印第5列+10.56
# awk  '/southem/{print $8 - 10}'  datafile
	匹配southerm,打印第八列-10
# awk  '/southem/{print $8 / 2 }'  datafile
	匹配southerm,打印第八列除以2
# awk  '/southem/{print $8 / 3 }'  datafile
	匹配southerm,打印第八列除以3
# awk  '/southem/{print $8 * 2 }'  datafile
	匹配southerm,打印第八列乘以2
# awk  '/southem/{print $8 % 2 }'  datafile
	取余数
# awk  '$3 ~ /^Suan/ {print "Percentage: "$6 + .2 " Volume: " $8}'  datafile
	第三列正则匹配以Suan开头的,打印第6列加0.2 并且打印第八列
# awk  '/^western/,/^eastern/'  datafile
	从以westem开头到以eastem开头的行
# awk  '{print ($7 > 4 ? "high "$7 : "low "$7)}'  datafile 
	//三目运算符 a?b:c 条件?成立结果1:不成立结果2
第三列小于4显示high$7
第三列大于4显示low$7
# awk  '$3 == "Chris" {$3 = "Christian"; print $0}'  datafile
	 赋值运算符,$3=christian
# awk  '/Derek/ {$8+=12; print $8}'  datafile  
	匹配Derek的行,为$8列赋值,$8=$8+12,再打印出$8
# awk  '{$7%=3; print $7}'  datafile 
	//$7 %= 3等价于$7 = $7 % 3
先将第七列取余,再赋值给第七列,打印第七列

你可能感兴趣的:(编程自动化运维,shell,awk,正则表达式,shell)