ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

awk命令

2021-11-04 00:01:37  阅读:212  来源: 互联网

标签:sbin nologin 命令 awk lp print root


一、awk简介

awk是一种编程语言,用于linux/unix下对于文本和数据进行处理,数据可以来自于标准输入、一个或多个文件,或是其他命令的输出。
awk处理文本和数据的方式:逐行扫描文件,默认是从第一行到最后一行,寻找匹配的行,并执行相应的操作
awk可以用"统计数据",如网站的访问量、访问ip量…;支持条件判断;支持for和while循环;正则表达式。

二、使用方式

awk有两种使用方式:命令行模式和脚本模式

命令行模式

语法:
awk 选项 ‘命令部分’ 文件名
如果要引用shell变量需用双引号引起

常用的选项介绍
-F 定义字段分割符号,默认的分隔符是"空格"
-v 定义变量并赋值

awk内置变量
在这里插入图片描述awk中BEGIN…END使用

​ BEGIN:表示在程序开始前执行

​ END :表示所有文件处理完后执行

​ 用法:'BEGIN{开始处理之前};{处理中};END{处理结束后}'

awk使用基础:

[root@local tmp]# cat a.txt						测试文件
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin

[root@local tmp]# awk 'NR==5' a.txt		**输出a.txt的第5行**
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

[root@local tmp]# awk 'NR==5,NR==7' a.txt		输出a.txt的第5到7行
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown

[root@local tmp]# awk '/root/' a.txt	过滤出包含root的行
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin

[root@local tmp]# awk -F: 'NR==5{print $1,$NF}' a.txt		指定分隔符为:输出第5行第1个字段和最后一给字段的值
lp /sbin/nologin

[root@local tmp]# awk -F: 'NR==5,NR==7{print $1,$NF}' a.txt	指定分隔符为:输出第5行到第7行第1个字段和最后一给字段的值
lp /sbin/nologin
sync /bin/sync
shutdown /sbin/shutdown

[root@local tmp]# awk -F: '/root/{print $1,$NF}' a.txt	过滤出包含root行的第个字段和最后一个字段的值
root /bin/bash
operator /sbin/nologin

[root@local tmp]# awk -F: '/^root/;/^lp/{print $1,$NF}' a.txt		输出以root开头和以lp开头行的第1列和最后一列
root:x:0:0:root:/root:/bin/bash
lp /sbin/nologin

[root@local tmp]# awk -F: '/^root/,/^lp/{print $1,$NF}' a.txt		输出以root开头到以lp开头行的第1列和最后一列
root /bin/bash
bin /sbin/nologin
daemon /sbin/nologin
adm /sbin/nologin
lp /sbin/nologin


内置变量分隔符举例(FS和OFS):
[root@local tmp]# awk 'BEGIN{FS="/"};/^root/;/^lp/{print $1,$NF}' a.txt		指定分隔符为/,输出以root开头和以lp开头行的第1列和最后一列
root:x:0:0:root: bash
lp:x:4:7:lp: nologin

[root@local tmp]# awk 'BEGIN{FS=":"};/^root/;/^lp/{print $1,$NF}' a.txt		指定分隔符为/,输出以root开头和以lp开头行的第1列和最后一列。这种写发和awk -F:  结果式一样的
root /bin/bash
lp /sbin/nologin

awk -F: 'BEGIN{OFS="@@@"};/^root/,/^lp/{print $1,$NF}' a.txt     	设置分隔符为:,输出的分隔符为@@,以root开头和以lp开头行的第1列和最后一列
root@@/bin/bash
bin@@/sbin/nologin
daemon@@/sbin/nologin
adm@@/sbin/nologin
lp@@/sbin/nologin

awk的使用进阶:

printf相当于echo -n
%s 字符类型  strings			
%d 数值类型	
- 表示左对齐,默认是右对齐
printf默认不会在行尾自动换行,加\n

演示:

[root@local tmp]#  awk -F: '{printf "%-15s %-10s %-15s\n", $1,$2,$3}' a.txt
root            x          0
bin             x          1
daemon          x          2
adm             x          3
lp              x          4
sync            x          5
shutdown        x          6
halt            x          7
mail            x          8
operator        x          11

awk变量定义:
awk -v 变量名=变量值 ‘awk语句’ 文件名

[root@local tmp]# awk -v num=5  'BEGIN{print num}' 	设置num的值为5,并打印awk的值
5
[root@local tmp]# awk -v num=7 -F: '{print $num}' a.txt		设置num的值为7,并于$连用,表示第7列单元
/bin/bash
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/bin/sync
/sbin/shutdown
/sbin/halt
/sbin/nologin
/sbin/nologin

BEGIN…END…实例

#在awk语句执行之前打印,执行后在打印。
[root@local tmp]# awk -F: 'BEGIN{ print "Login_user\t\tLogin_shell\n****************************"};NR==1,NR==5{print $1"\t\t"$NF};END{print "****************************"}' a.txt
Login_user		Login_shell
****************************
root		/bin/bash
bin			/sbin/nologin
daemon		/sbin/nologin
adm			/sbin/nologin
lp			/sbin/nologin
****************************

#相比较上面一个命令,结果格式化了输出
[root@local tmp]# awk -F: 'BEGIN{print"u_name\t\th_dir\t\tshell\n***************************"};NR==1,NR==5{printf "%-20s %-20s %-20s\n",$1,$(NF-1),$NF};END{print "****************************"}' a.txt
u_name		h_dir		shell
***************************
root                 /root                /bin/bash
bin                  /bin                 /sbin/nologin
daemon               /sbin                /sbin/nologin
adm                  /var/adm             /sbin/nologin
lp                   /var/spool/lpd       /sbin/nologin
****************************

awk和正则的综合运用

 运算符  说明     
 `==      等于     
 !=      不等于   
 >       大于     
 <       小于     
 >=      大于等于 
 <=      小于等于 
 ~       匹配     
 !~      不匹配   
 !       逻辑非   
 &&      逻辑与   
 \|\|    逻辑或   `

实例

从第一行开始匹配到以lp开头行
awk -F: 'NR==1,/^lp/{print $0 }' a.txt
从第一行到第5行          
awk -F: 'NR==1,NR==5{print $0 }' a.txt
从以lp开头的行匹配到第10行       
awk -F: '/^lp/,NR==10{print $0 }' a.txt
从以root开头的行匹配到以lp开头的行       
awk -F: '/^root/,/^lp/{print $0}' a.txt
打印以root开头或者以lp开头的行            
awk -F: '/^root/ || /^lp/{print $0}' a.txt
awk -F: '/^root/;/^lp/{print $0}' a.txt
显示5-10行   
awk -F: 'NR>=5 && NR<=10 {print $0}' a.txt   
awk -F: 'NR<10 && NR>5 {print $0}' a.txt
打印1-9行以root开头的内容:
awk 'NR>=1 && NR<=9 && $0 ~ /^root/{print $0}' a.txt
awk 'NR>=1 && NR<=9 && /^root/' a.txt

显示可以登录系统的用户名 
[root@local tmp]# awk -F: '$0 ~ /\/bin\/bash/{print $1}' /etc/passwd
root
yyy
zzz

打印出系统中普通用户的UID和用户名
[root@local tmp]# awk -F: 'BEGIN{print "UID\tUSERNAME"} {if($3>=1000 && $3 !=65534 ) {print $3"\t"$1} }' /etc/passwd
UID	USERNAME
1001	yyy
1002	zzz

awk的脚本编程
㈠ 流程控制语句
① if结构
格式:
{ if(表达式){语句1;语句2;…}}

[root@local tmp]# awk -F: '{if($3>=1000 && $3<=60000) {print $1,$3} }' /etc/passwd
yyy 1001
zzz 1002

② if…else结构
格式:
{if(表达式){语句;语句;…}else{语句;语句;…}}

通过if..else结构判断用户是否是普通用户
awk -F: '{ if($3>=500 && $3 != 65534) {print $1"是普通用户"} else {print $1,"不是普通用户"}}' b.txt

③ if…elif…else结构
格式:
{ if(表达式1){语句;语句;…}else if(表达式2){语句;语句;…}else if(表达式3){语句;语句;…}else{语句;语句;…}}

# if...elif...else判断用户的类型
awk -F: '{ if($3==0) {print $1,":是管理员"} else if($3>=1 && $3<=999 || $3==65534 ) {print $1,":是系统用户"} else {print $1,":是普通用户"}}' /etc/passwd

#通过if...elif...else统计用户类型的个数
awk -F: '{ if($3==0) {i++} else if($3>=1 && $3<=999 || $3==65534 ) {j++} else {k++}};END{print "管理员个数为:"i "\n系统用户个数为:"j"\n普通用户的个数为:"k }' /etc/passwd



awk -F: '{if($3==0) {i++} else if($3>=1 && $3<500 || $3==65534){j++} else {k++}};END{print "管理员个数为:" i RS "系统用户个数为:"j RS "普通用户的个数为:"k }' /etc/passwd

(二)、 循环语句
① for循环

#打印1~5
awk 'BEGIN { for(i=1;i<=5;i++) {print i} }'
for ((i=1;i<=5;i++));do echo $i;done|awk '{print $0}'
awk 'BEGIN{ for(i=1;i<=5;i++) {print i} }'
awk 'BEGIN{ for(i=1;i<=5;i++) print i }'

计算1-5的和
awk 'BEGIN{sum=0;for(i=1;i<=5;i++) sum+=i;print sum}'
awk 'BEGIN{for(i=1;i<=5;i++) (sum+=i);{print sum}}'
awk 'BEGIN{for(i=1;i<=5;i++) (sum+=i);print sum}'

② while循环

#打印1~5
i=1;while (($i<=5));do echo $i;let i++;done
awk 'BEGIN { i=1;while(i<=5) {print i;i++} }'
awk 'BEGIN{i=1;while(i<=5) {print i;i++} }'

计算1-5的和
awk 'BEGIN{i=1;sum=0;while(i<=5) {sum+=i;i++}; print sum }'
awk 'BEGIN {i=1;while(i<=5) {(sum+=i) i++};print sum }'

③ 嵌套循环

普通的shell脚本实现
#!/bin/bash
for ((y=1;y<=5;y++))
do
	for ((x=1;x<=$y;x++))
	do
		echo -n $x	
	done
echo
done

使用awk实现
awk 'BEGIN{ for(y=1;y<=5;y++) {for(x=1;x<=y;x++) {printf x} ;print } }'
awk 'BEGIN{ y=1;while(y<=5) { for(x=1;x<=y;x++) {printf x};y++;print}}'

break 条件满足的时候跳出循环
continue 条件满足的时候跳过当次循环

awk统计案例

#统计/etc/passwd中各种bash的数量
awk -F: '{ shells[$NF]++ };END{for (i in shells) {print i,shells[i]} }' /etc/passwd

#统计网站访问状态
ss -antp|grep 80|awk '{states[$1]++};END{for(i in states){print i,states[i]}}'

统计访问网站的每个IP的数量
netstat -ant |grep :80 |awk -F: '{ip_count[$8]++};END{for(i in ip_count){print i,ip_count[i]} }' |sort

ss -an |grep :80 |awk -F":" '!/LISTEN/{ip_count[$(NF-1)]++};END{for(i in ip_count){print i,ip_count[i]}}' |sort -k2 -rn |head

统计网站日志中PV量
统计Apache/Nginx日志中某一天的PV量
grep '27/Jul/2017' mysqladmin.cc-access_log |wc -l

统计Apache/Nginx日志中某一天不同IP的访问量
grep '27/Jul/2021' mysqladmin.cc-access_log |awk '{ips[$1]++};END{for(i in ips){print i,ips[i]} }' |sort -k2 -rn |head
grep '27/Jul/2021' access.log |awk '{ips[$1]++};END{for(i in ips){print i,ips[i]} }' |awk '$2>100' |sort -k2 -rn

标签:sbin,nologin,命令,awk,lp,print,root
来源: https://blog.csdn.net/weixin_45939085/article/details/121129226

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有