awk的使用

awk
awk 有列的概念
awk 功能等于 grep
awk 原理等于 sed

awk '条件 命令'
awk 'BEGIN{} 条件{} END{}' 文件
初始化 总结
BEGIN{}在读文件内容之前执行
条件{} 在读文件内容时执行
END{}在读文件内容之后执行

主要用法
--格式1:前置命令|awk [选项] '[条件]{编辑指令}'
--格式2:awk [选项] '[条件]{编辑指令}' 文件
多条语句可以分号分隔
print是最常用的指令

命令格式解析
常用命令选项
-F:指定分隔符,可省略(默认为空格或者Tab位)
-f : 调用awk脚本进去处理
-v:调用外部shell变量

awk 内置变量
有特殊含义,可以直接使用
FS 保存或设置字段分隔符,例如 FS= ":"
$n 指定分隔的第n个字段,如$1、$3分别表示第1、第3列
$0 当前读入的整行文本内容
NF 记录当前处理行的字段个数(列数)
NR 记录当前已读入行的数量(行数)
FNR 保存当前处理行在原文本内的序号(行号)
FILENAME 当前处理的文件名
ENVIRON 调用Shell环境变量,格式:ENVIRON["变量名"]

 

while :
do
awk '/Failed/{print $11}' /var/log/secure|uniq -c >> ip.txt
sleep 10
done

[root@vh02 ~]# ifconfig|awk -F"[: ]" '/inet addr:/{print $13}'
192.168.4.2
192.168.2.2
127.0.0.1


[root@vh01 script]# awk -F: '{print $1,$2}' /etc/passwd

[root@vh01 script]# awk '{print "我不是潘金莲\t" "速度与激情\t" "魔兽"}' a.txt
我不是潘金莲 速度与激情 魔兽
我不是潘金莲 速度与激情 魔兽
我不是潘金莲 速度与激情 魔兽

[root@vh01 script]# awk -F: '/bash/{print "用户名为:" $1,"\t\tID是:"$3,"\t\tsheel是"$7 }' /etc/passwd
用户名为:root ID是:0 sheel是/bin/bash
用户名为:zhangsan ID是:500 sheel是/bin/bash
用户名为:tom ID是:501 sheel是/bin/bash
用户名为:user ID是:502 sheel是/bin/bash

[root@vh01 script]# awk '{print "第"FNR"行," "有"NF"列"}' a.txt
第1行,有1列
第2行,有1列
第3行,有1列


awk 'BEGIN{} 条件{} END{}' 文件
初始化 总结
BEGIN{}在读文件内容之前执行
条件{} 在读文件内容时执行
BEGIN{}在读文件内容之后执行

awk过滤的时机
1、在所有行前处理,BEGIN{}
--在读入第一行文本之前执行
--一般用来初始化操作
2、逐行处理,{}
--逐行读入文本执行相应的处理
--是最常见的编辑指令块
3、在所有行后处理,END{}
--处理完最后一行文本之后执行
--一般用来输出处理结果

可以单独使用,也可以同时一起使用

处理条件概述
-所有的行全部处理并输出吗?
-怎么限制处理的条件?
-根据多个条件来处理指定的行?

条件的表现形式
--正则表达式
--数值、字符串比较
--逻辑比较
--运算符

条件测试
1、正则
~匹配 !~不匹配
[root@vh01 script]# awk -F: '/root/' /etc/passwd 找出有root的行
[root@vh01 script]# awk -F: '$1~/root/' /etc/passwd 在第一列找出有root
[root@vh01 script]# awk -F: '$2!~/x/' /etc/passwd 找出不要密码的登录的用户

2、数值比较 > < == != >= <=
== 等于 !=不等于
> 大于 >=大于或等于
< 大于 <=小于或等于
[root@vh01 script]# awk -F: '$3<10{print$1,$3}' /etc/passwd 找出ID号小于10的用户
[root@vh01 script]# awk -F: '$3> 500{print$1,$3}' /etc/passwd 找出ID号大于500的用户

3、字符串的对比
[root@vh01 script]# awk -F: '$1=="root"' /etc/passwd 在第一列找出root用户的行

4、逻辑比较测试
&&逻辑与:期望多个条件都成立
|| 逻辑或:只要有一个条件成立即满足要求
[root@vh01 script]# awk -F: '$3>=0&&$3<2{print $1,$3}' /etc/passwd
root 0
bin 1
[root@vh01 script]# awk -F: '$3==1||$3==7{print $1,$3}' /etc/passwd
bin 1
halt 7

列出UID间于501~505的用户详细信息
[root@vh01 script]# awk -F: '$3>=501&&$3<=505' /etc/passwd

输出/etc/hosts文件内以127或者192开头的记录
[root@vh01 script]# awk '/^(127|192)/' /etc/hosts
[root@vh01 script]# awk '$1~/^127/||$1~/^192/' /etc/hosts

列出100以内整数中7的倍数或是含7的数
[root@vh01 script]# seq 100|awk '$1%7==0 || $1~7'

 

[root@vh01 script]# awk -F: 'BEGIN{print "用户名""\t\tUID""\t\t解释器"}{print $1"\t\t"$3"\t\t"$7}END{print"总用户数为"NR}' /etc/passwd

[root@vh01 script]# awk -F: 'BEGIN{print "用户名""\t\tUID""\t\t解释器"}/bash/{print $1"\t\t"$3"\t\t"$7}END{print"总用 户数为"NR}' /etc/passwd
用户名 UID 解释器
root 0 /bin/bash
zhangsan 500 /bin/bash
tom 501 /bin/bash
user 502 /bin/bash
lucy 503 /bin/bash
jim 504 /bin/bash
bob 505 /bin/bash
harry 506 /bin/bash
liang 507 /bin/bash
qq 508 /bin/bash
mike 509 /bin/bash
总用户数为38

[root@vh01 script]# awk 'BEGIN{x=1;y=2;z=x+y;print z}'
3
[root@vh01 script]# awk 'BEGIN{x=1;y=2.33;z=x+y;print z}'
3.33

 

[root@vh01 script]# awk 'BEGIN{I=0}/bash/{i++}END{print i}' /etc/passwd
11
[root@vh01 script]# awk -F: 'BEGIN{print "用户名""\t\tUID""\t\t解释器";i=0}/bash/{print $1"\t\t"$3"\t\t"$7;i++}END{print"总用户数为"i}' /etc/passwd
用户名 UID 解释器
root 0 /bin/bash
zhangsan 500 /bin/bash
tom 501 /bin/bash
user 502 /bin/bash
lucy 503 /bin/bash
jim 504 /bin/bash
bob 505 /bin/bash
harry 506 /bin/bash
liang 507 /bin/bash
qq 508 /bin/bash
mike 509 /bin/bash
总用户数为11


[root@vh01 script]# awk 'BEGIN{print NR} END{print NR}' /etc/passwd
0
38

过滤用户名以及对应的密码:
[root@vh01 script]# vim m3.sh
#!/bin/bash
user=`awk -F: '$7~/bash/{print$1}' /etc/passwd`
for i in $user
do
pass=`awk -F: -v X=$i '$1==X{print$2}' /etc/shadow`
echo "$i====>>$pass"
done


[root@vh01 script]# vim ./m4.sh
#!/bin/bash
user=$(awk -F: '$7~/bash/{print$1}' /etc/passwd)
for i in $user
do
awk -F: -v X=$i '$1==X{print$1"====>"$2}' /etc/shadow >>/tmp/1.txt
done
cat /tmp/1.txt
-v X=$i -v是在awk定义变量

awk 'BEGIN{} 条件{} END{}' 文件
分支结构
单分支
if(条件){编辑指令}
双分支
if(条件){编辑指令1}else{编辑指令2}
多分支
if(条件){编辑指令1}else if{编辑指令2}... ...
else{编辑指令N}

普通用户个数,系统用户个数统计
[root@vh01 script]# awk -F: '$3>=500{x++}END{print x}' /etc/passwd
11
[root@vh01 script]# awk -F: '$3<500{x++}END{print x}' /etc/passwd
27

使用awk的if语句进行普通用户个数,系统用户个数统计
[root@vh01 script]# awk -F: '{ if($3<500){x++}else{y++} } END{print x,y}' /etc/passwd
27 11
[root@vh01 script]# awk -F: 'BEGIN{x=0;y=0}{ if($3<500){x++}else{y++} } END{print x,y}' /etc/passwd
27 11


循环结构
for循环
for(初值;条件;步长){编辑指令}
[root@vh01 script]# awk 'BEGIN{for(i=1;i<=5;i++){print i}}'

while 循环
while(条件){编辑指令}

do while 循环
do{编辑指令}while(条件)

应用示例 (理解与排版)
统计/etc/passwd文件内"root"出现次数
利用-F[:/] 表示分隔符为:或者/
[root@vh01 script]# awk -F[:/] '{i=1}{while(i<=NF){if($i~/root/){j++};i++}} END{print j}' /etc/passwd
4
[root@vh01 script]# awk -F"[:/]" '{i=1}{while(i<=NF){if($i=="root"){j++};i++}} END{print j}' /etc/passwd
4

[root@vh01 script]# cat a.txt
二钩子 12 1.8 boy
二妮子 15 1.6 girl
三妮子 18 1.7 girl
小李子 17 1.7 boy
[root@vh01 script]# awk '{if($4=="boy"){print $3}else{print $2}}' a.txt
1.8
15
18
1.7

awk的数组:
定义数组:
变量[下标]=值
变量[下标]=值

提取数组的值
提取一个值:变量[下标]
提取所有的值:
for (i in 变量){print 变量[i]}

awk 'BEGIN{ a[0]=1;a[1]=2;a[2]=3;for (i in a){print a[i]} }'

 


awk中数组的运用

[root@vh03 ~]# yum -y install httpd
[root@vh03 ~]# service httpd start
[root@vh03 ~]# service httpd status
[root@vh03 ~]# netstat -anptu|grep :80
[root@room1pc01 桌面]# ab -c 200 -n 20000 http://192.168.4.3/
[root@vh01 script]# ab -c 200 -n 20000 http://192.168.4.3/
[root@vh02 ~]# ab -c 200 -n 20000 http://192.168.4.3/
[root@vh03 ~]# wc -l /var/log/httpd/access_log
60256 /var/log/httpd/access_log
[root@vh03 ~]# awk '{x[$1]++}END{for(i in x){print i,x[i]}}' /var/log/httpd/access_log
192.168.4.1 20000
192.168.4.2 20015
192.168.4.254 20000
::1 241


awk '{x[$1]++}END{ for(i in x){print i,x[i]} }' 文件
在哪里都可以套用,只需要改$1,其他不变。

posted @ 2021-09-17 14:01  Linux刀客  阅读(253)  评论(0编辑  收藏  举报