Linux:awk进阶(13)
  ehrZuhofWJiC 2024年05月17日 28 0

Linux:shell脚本:基础使用(6)《正则表达式-awk工具》_awk 分隔符 正则表达式ops_request_misc=%257B%2522request%255Fid%2522%253A%2522170842394816800185872161%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=170842394816800185872161&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_ecpm_v1~rank_v31_ecpm-1-132406372-null-null.nonecase&utm_term=awk&spm=1018.2226.3001.4450awk的基础文章


1.awk的作用:一种编程语言,用于在linux/unix下对文本和数据进行处理。数据可以来自标准输入stdin、一个或多个文件,或其它命令的输出。简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片切开的部分再进行各种分析处理擅长取行、取列、过滤。


 2.语法:

awk  [选项]  '模式{  动作(action) }'  文件1  文件2  ...

选项:     -F    指定输入分隔符,可以是字符串或正则表达式;

最常见的动作:     print、printf


切片筛选案例

chkconfig --list |grep 3:启用 |awk '{print $1}'

#找出再init3 下开机自启的服务名
tail -1 /etc/passwd |awk -F ':' 'BEGIN{OFS="---"}{print $1,$6,$7}'   

#OFS指定输出分隔符
ifconfig ens33 |awk -F '[ :]+' 'NR==2 {print $3}'

#找出ip地址
ifconfig ens33 |awk -F '[ :]+' 'NR==2 {print "ens_ip="$3}' 

#查询ip,提示出ens_ip= “ip地址”
awk 'BEGIN {print "line one \nline two\nline three"}'

#line one
#line two
#line three
awk -F':' 'BEGIN {print "line one \nline two\nline three",OFS="----------"}''{print $1,$2}''END {print "line one \nline two\nline three"}' /etc/passwd

#这个你输出一下就知道了

匹配范围

 

注解:

  $1==""                                               ##精确匹配等于

  $1!=""                                                ##精确匹配不等于

  $1~""                                                  ##包含匹配等于

  $1!~""                                                ##包含匹配不等于

awk -F : '$3==3,$3==10{print $1,$3,$7}' /etc/passwd

awk -F : '$1=="root",$1=="adm"{print $1,$3,$7}' /etc/passwd

awk -F : '/^r/,/^a/{print $1,$3,$7}' /etc/passwd

awk -F ':' '($7!~"/sbin"){print $1,$7}' /etc/passwd                   

         

##查找$7不包含/sbin作为条件,进行打印

awk -F ':' '($7!="/bin/bash")&&($7!="/sbin/nologin"){print $1}' /etc/passwd             

   

##查找$7不等于/bin/bash并且$7不等于/sbin/nologin作为条件,进行打印

awk -F ':' '($5~"99999")&&($2=="*"){print $1,$5}' /etc/shadow                   

                     

##查找$5包含99999并且$2等于*作为条件,进行打印;


awk区块原理 

BEGIN { 动作 }     #开始处理第一行文本之前的操作

{ 动作 }           #针对每一行文本的处理操作

END { 动作 }       #处理完最后一行文本之后的操作

执行流程:

 首先执行 BEGIN { } 区块中的初始化操作;

 然后从指定的数据文件中循环读取一个数据行(自动更新 NF、 NR、 $0、 $1…… 等内建变量的值),并执行'模式或条件{ 动作 }';

 最后执行 END { } 区块中的后续处理操作。

awk -F : 'BEGIN{printf "%-20s%-20s%-20s\n","UserName","ID","Shell"}{printf "%-20s%-20s%-20s\n",$1,$3,$7}' /etc/passwd   

Linux:awk进阶(13)

 ifconfig ens33 |awk  'NR==2{print $2,$4}'|awk 'BEGIN{OFS=" / "}{print "IP="$1,"MASK="$2}'

Linux:awk进阶(13)

 


awk的变量

FS:列分隔符,默认位空白

RS:行分隔符,默认位换行符

OFS:输出列分隔符

ORS :输出行分隔符

awk内置变量:

NR:处理中行数

FNR:单个文件的行数

NF:列的个数

 

awk 'BEGIN{print test="123"  $test}'
awk -v test="123" 'BEGIN{print test}'

两种定义变量的方法 


 printf的使用

格式:printf  "格式",列表1,列表2  ...

特征:

a.必须指定format(格式),用于指定后面item(列表)的输出格式

b.printf语句不会自动打印换行符:\n

c.format格式以%加一个字符,如下:

  %c:显示字符的ASCII码

  %d,%i:十进制整数

  %f:显示浮点数(小数)

  %s:显示字符串

  %u:无符号整数

  %%:显示%

d.修饰符:N:显示宽度,-:左对齐,+:显示数值符号,如%-c(左对齐)

chkconfig --list |grep 3:开 |awk '{printf "%-10s\n",$1}'
awk -F : '{printf "%-15s %-10d %-10s\n",$1,$3,$7}' /etc/passwd

awk的操作符:

算数操作符: x^y、x/y、x+y、x-y、x%y

比较操作符:>、<、>=、<=、==、!=

逻辑操作符:&&、||、!


awk常见的模式类型

正则表达式(regexp):awk -F : '/^u/{print $1}' /etc/passwd

表达式(expression):值位非0或位非空是满足条件,如$1 ~ /foo/或 $1 == "root"

awk -F : '$3>=500{print $1,$3,$7}' /etc/passwd                               ##打印普通用户

awk -F : '$3+1<=100&&$3+1>=10{print $1,$3,$7}' /etc/passwd  ##UID在10-100之间的用户

awk -F : '$2=="!!"{print $1,$2}' /etc/shadow                                    ##检查未初始化密码的用户

passwd  -d  u01

awk -F : '$2==""{print $1}' /etc/shadow                                             ##打印密码为空的用户

awk -F : '$7~"bash$"{print $1,$3,$7}' /etc/passwd                         ##匹配$7为bash结束行

awk -F : '$7!~"bash$"{print $1,$3,$7}' /etc/passwd

 Linux:awk进阶(13)

Linux:awk进阶(13) Linux:awk进阶(13)


if-else判断 

语法:if  (条件表达式)  命令  操作1; else   命令  操作2

案例:

awk -F : '$7~"bash"{if ($1=="root") print $1, "admin";else print $1, "Common User"}' /etc/passwd   ##第七列是bash,如果第一列是root打印root admin,否则打印出第一列 common user

awk -F : -v sum=0 '{if ($3>=500) sum++}END{print sum}' /etc/passwd   ##输出普通用户的数量

awk -F : '$7~"bash$"{if ($1=="root") printf "%-15s: %s\n",$1,"admin";else printf "%-15s: %s\n",$1,"common user"}' /etc/passwd                                        ##使用printf打印


while循环:

循环字段(列),awk本身就是行的循环

语法:while  (条件){语句1;语句2;...}

案例:

awk -F: '{i=1;while (i<=3) {print $i;i++}}' /etc/passwd                              ##循环打印前3列

awk -F : '{i=1;while (i<NF) {if (length($i)<=4) print $i;i++}}' /etc/passwd                          ##循环整行,并打印出长度小于4的字段列

 


for循环

语法:for  (初始变量;条件;变量自加){语句1, 语句2,...}

案例:

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


 数组

语法:数组名[下标]

解释:awk中数组(array)的下标(index-expression)可以使用任意字符串;需要注意的是,如果某数据组元素事先不存在,那么在引用其时,awk会自动创建此元素并初始化为空串;因此,要判断某数据组中是否存在某元素,需要使用“下标  in  数组”的方式。要遍历数组中的每一个元素,需要使用如下的特殊结构:for (变量  in  数组) { 语句1, ... }

案例:

[root@localhost ~]# netstat -ant

Active Internet connections (servers and established)

Proto Recv-Q Send-Q Local Address    Foreign Address        State     

tcp        0      0 0.0.0.0:22       0.0.0.0:*           LISTEN     

tcp        0      0 127.0.0.1:25     0.0.0.0:*           LISTEN     

tcp        0      0 192.168.1.106:22 192.168.1.101:36318 ESTABLISHED

以上命令显示的结果中,每一行最后一个字段为状态,若要统计每种状态的个数,只需要将state作为数组下标,由于awk本身就是一个行的循环,所以只需要给数字自加1(++)即可实现统计,具体操作如下:

[root@localhost ~]# netstat -ant |awk '/^tcp|^udp/{state[$6]++}END{for(i in state){print i,state[i]}}'                                ##state[$6]++表示定义数组state[]、$6是下标,++表示自加1

[root@localhost ~]# netstat -ant |awk '/^tcp/{S[$NF]++}END{for(a in S) print a, S[a]}'

[root@localhost ~]# awk '{counts[$1]++}END{for (url in counts) print url,"access times:",counts[url]}' /var/log/httpd/access_log                                    ##查看http的访问

[root@localhost ~]# awk '{AH[$1]++}END{for (i in AH) printf "%-20s:%s\n", i, AH[i]}' /var/log/httpd/access_log

 

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2024年05月17日 0

暂无评论

推荐阅读
  ehrZuhofWJiC   2024年05月17日   28   0   0 服务器linux
ehrZuhofWJiC