awk命令详解


参考书籍:《Linux Shell核心编程指南》——丁明一

一、概述

awk是专门为文本处理设计的编程语言,是一门数据驱动的编程语言,与sed类似都是以数据驱动的行处理软件,主要用于数据扫描、过滤、统计汇总工作,数据可以来自标准输入、管道或者文件。

awk在20世纪70年代诞生与贝尔实验室。现在使用的版本是1988年发布的Gnu awk

二、基础语法

2.1.记录与字段

awk是一种处理文本文件的编程语言,文件的每行数据都被称为记录,默认以空格或制表符为分隔符,每条记录被分成若干字段(列),awk每次从文件中读取一条记录。

语法格式:

awk [选项] ‘条件{动作}  条件{动作} ... ...’  文件名

2.2.内置变量

awk语法由一系列条件和动作组成,在花括号内可以有多个动作,多个动作之间用分号分隔,在多个条件和动作之间可以有若干空格,也可以没有。

如果没有指定条件则匹配所有数据,如果没有指定动作则默认为print打印。

在这里插入图片描述

# free | awk '{print $2}'		#逐行打印第2列
used
3062364
0
free | awk '{print NR}'			#输出行号
free | awk '{print NF}'			#输出每行数据的列数
awk '{print $NF}' /tmp/hosts	#打印每行数据的最后一列
awk '{print $(NF-1)}' /tmp/hosts	#打印每行倒数第二列

cp /etc/hosts /tmp/hosts
awk '{print $0}' /tmp/hosts		#打印每行全部内容

在这里插入图片描述


同样是输出行号,NR将所有文件的数据视为一个数据流,而FNR则是将多个文件的数据视为独立的若干个数据流,遇到新文件时行号从1开始重新递增。

2.3.自定义变量

awk -v x="bob" -v y=10 '{print x,y}' /tmp/hosts

在这里插入图片描述

2.4.调用系统变量

awk -v shell=$SHELL '{print shell}' /tmp/hosts	或者
awk '{print "'$SHELL'"}' /tmp/hosts		#双引号加单引号组合能正确获取系统变量

在这里插入图片描述

2.5.自定义分隔符

默认以空格、换行符、制表符作为分隔符,使用-F可以指定分隔符

awk -F: '{print $1}' /etc/passwd		#以冒号作为分隔符
awk -F"[:,_]" '{print $1}' /etc/passwd	#使用集合定义分隔符

2.6.内置变量RS、OFS、ORS

RS

内置变量RS保存的是输入数据的行分隔符,默认为\n,可以指定其它字符作为行分隔符

awk -v RS="." '{print $1}' /tmp/hosts		#指定.作为行分隔符

OFS

保存的是输出字段的分隔符(列分隔符),默认为空格

awk -v OFS="-" '{print $1,$2}' /tmp/hosts	#以"-"作为字段分隔符
awk -v OFS="\t" '{print $1,$2}' /tmp/hosts	#以Tab制表符为字段分隔符
awk -v OFS=". " '{print NR,$0}' /tmp/hosts	#在每行前面加上行号和点

在这里插入图片描述

ORS

保存的是输出记录的分隔符

awk -v ORS="-" '{print $1}' /tmp/hosts

在这里插入图片描述

2.7.print指令

可以输出常量和变量,如果是字符串常量需要用双引号括起来,数字常量可以直接打印

awk '{print 123}' /tmp/hosts
awk '{print "IP:",$1}' /tmp/hosts
awk '{print "第1列:"$1,"\t第2列:"$2}' /tmp/hosts

在这里插入图片描述

2.8.条件匹配

awk支持使用正则进行模糊匹配,也支持字符串和数字的精确匹配,并且支持逻辑与和逻辑或。

在这里插入图片描述

awk '/localhost/' /tmp/hosts
awk '$3~/local/' /tmp/hosts		#每行的第3列去匹配local
awk '$3~/local/{print $1,$2}' /tmp/hosts
awk '$2=="localhost"' /tmp/hosts		#第2列精确匹配localhost
awk '$2!="localhost"' /tmp/hosts		#取反
awk -F: '$3<=10' /etc/passwd			#第3列小于等于10的行
awk -F: 'NR==10' /etc/passwd			#仅显示第10行
awk -F: '$3>1 && $3<5' /etc/passwd		#逻辑与
awk -F: '$3==1 || $3==5' /etc/passwd	#逻辑或

2.9.BEGIN和END

BEGIN导致动作指令仅在读取任何数据记录之前执行一次,END导致动作指令仅在读取完所有数据记录后执行一次

BEGIN可以进行数据初始化,END可以进行数据汇总

awk 'BEGIN{print "OK"}'
awk 'END{print NR}' /etc/passwd		#打印最后一行的行号

在这里插入图片描述

awk -F: 'BEGIN{print "用户名 UID 解释器"} \
{print $1,$3,$7} \
END {print "共有"NR"个账号."}' /etc/passwd | column -t	#column实现格式化输出,并按升序排序

在这里插入图片描述


中间省略

在这里插入图片描述

2.10.数字计算

[15:30:04][root@localhost:~]# awk 'BEGIN{print 2+3}'
5
[15:30:13][root@localhost:~]# awk 'BEGIN{print 2*3}'
6
[15:30:17][root@localhost:~]# awk 'BEGIN{print 2/5}'
0.4
[15:30:31][root@localhost:~]# awk 'BEGIN{print 5%2}'
1
[15:30:45][root@localhost:~]# awk 'BEGIN{print 5**2}'
25
[15:30:52][root@localhost:~]# awk 'BEGIN{x=5;y=2;print x-y}'
3
[15:31:27][root@localhost:~]# awk 'BEGIN{x=1;x++;print x}'
2
[15:31:46][root@localhost:~]# awk 'BEGIN{x=1;x+=1;print x}'
2

awk中变量不需定义就可以直接使用,作为字符处理时未定义的变量默认值为空,作为数字处理时未定义的变量默认值为0

awk 'BEGIN{print "["x"]","["y"]"}'		#x和y默认为空
awk 'BEGIN{print x+8}'					#x默认为0

在这里插入图片描述

2.11.循环计数

awk '/bash$/{x++} END{print x}' /etc/passwd

逐行读取/etc/passwd文件,x初始值为0,匹配到以bash结尾的行时自加1,最后打印x的值。
此处表明以bash结尾的行共有5行

在这里插入图片描述

who | awk '$1=="root"{x++} END{print x}'	#统计有多少个客户端登录root
seq 200 | awk '$1%6==0 && $1~/6/'			#打印1~200之间能被6整除且包含数字6的整数数字

在这里插入图片描述

三、awk条件判断

if判断后面如果只有一个动作指令,则花括号{}可省略,如果if判断后面的指令为多条指令则需要使用花括号括起来,多个指令使用分号分隔。

3.1.单分支语句

语法:

if(判断条件){
动作指令序列;
}

查找cpu使用率大于0.3的进程

ps -eo user,pid,pcpu,comm | awk '{if($3>0.5) print}'

在这里插入图片描述

3.2.双分支if语句

语法:

if(判断条件){
动作指令1;
} else {
动作指令2;
}

统计系统用户与普通用户的个数

awk -F: '{if($3<1000){x++} else{y++}} END{print "系统用户个数:"x"","普通用户个数:"y""}' /etc/passwd

在这里插入图片描述

3.3.多分支语句

if(判断条件){
动作指令1;
} else if(判断条件2){
动作指令2;
} else {
动作指令N;
}

四、awk数组与循环

awk 'BEGIN{a[0]=11;a[1]=12;print a[0],a[1]}'

awk 'BEGIN{ \
tom["age"]=22; \
tom["addr"]="sichuan"; \
print tom["age"],tom["addr"] \
}'

在这里插入图片描述

4.1.遍历数组

语法:

for(变量 in 数组名){
动作指令序列
}

示例:

awk 'BEGIN{ \
> a[0]=1;a[11]=22;a["book"]=32;a["work"]="home"; \
> for(i in a){print i,a[i]} \
> }'

输出是无序的。i是索引,a[i]是值

在这里插入图片描述


成员关系判断

awk 'BEGIN{ \
> a[11]=1;a[22]=2; \
> if("22" in a){print "yse"} else {print no} \
> }'

在这里插入图片描述

4.2.for循环

采用与C语言一样的语法格式

for(表达式1;表达式2;表达式3) {
动作指令序列
}
awk 'BEGIN{ for (i=1;i<=4;i++) {print i}}'

awk -F: '{ \
for(i=1;i<=NF;i++) \
> {if($i=="root") x++} \
> } END {print x}' /etc/passwd

统计root出现的次数。
这里面包含了两个循环,一个是隐含循环,awk会逐行处理数据;一个是for循环每列的值,如果等于root,就让x自加1,最后打印x的值

在这里插入图片描述

4.3.while循环

语法:

while(条件判断){
动作指令序列;
}

示例:

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

4.4.中断语句

与shell类似,awk提供了continue、break、exit循环中断语句。

awk 'BEGIN{ \
i=0;
while(i<=5) { \
i++; \
if(i==3) {continue}; \
print i \
}; \
} \
END {print "END"}' /tmp/hosts

在这里插入图片描述

五、awk函数

5.1.内置I/O函数

getline函数

能让awk立刻读取下一行数据(读取下一条记录并复制给$0,并重新设置NF、NR和FNR)

#解决挂载逻辑卷时,分区信息跨行显示的问题
df -h | awk '{if(NF==1) {getline;print $3}; if(NF==6) {print $4}}'

next函数

停止处理当前的输入记录,立刻读取下一条记录并返回awk程序的第一个模式匹配重新处理数据。
有点类似于循环语句中的continue,不会执行当次循环的后续语句

awk -F: '/root/{getline;print "next line:",$0} {print "normal line"}' /etc/passwd

在这里插入图片描述

awk -F: '/root/{next;print "next line:",$0} {print "normal line"}' /etc/passwd

在这里插入图片描述


经比较可以看出,getline,会继续执行后续的指令print “next line:”,而next不会执行后续指令,而是重新开始匹配

system(命令)函数

可以直接在awk中调用shell命令,会启动一个新shell进程执行命令

awk 'BEGIN{system("ls")}'
awk '{system("echo date:"$0)}' /tmp/hosts

在这里插入图片描述

5.2.内置数值函数

cos(expr)、sin(expr)、sqrt(expr)

int(expr)函数

可以对小数取整

[14:23:42][root@localhost:~]# awk 'BEGIN{print int(6.8)}'
6

rand()函数

返回0到1之间的随机数

awk 'BEGIN{print rand()}'
awk 'BEGIN{for(i=1;i<=5;i++) print int(100*rand())}'	#生成5个100以内的随机数

在这里插入图片描述

srand([expr])

可以使用expr定义新的随机数种子,没有expr时则使用当前系统的时间为随机数种子

awk 'BEGIN{srand();print rand()}'		#使用时间做随机数种子
awk 'BEGIN{srand(22);print rand()}'		#使用数值做随机数种子

在这里插入图片描述

5.3.内置字符串函数

length([s])函数

可以统计字符串s的长度,如果不指定字符串s则统计$0的长度

awk 'BEGIN{test="hello"; print length(test)}'		#打印字符串长度
awk 'BEGIN{t[0]="hi";t[1]="the"; print length(t)}'	#返回数组元素个数
awk '{print length()}' /etc/shells					#返回文件每行的字符长度

在这里插入图片描述

index(字符串1,字符串2)

返回字符串2在字符串1中的位置

awk 'BEGIN{test="hello";print index(test,"l")}'

在这里插入图片描述

match(s,r)

根据正则表达式r返回其在字符串s中的位置坐标

[14:47:52][root@localhost:~]# awk 'BEGIN{print match("How much","[a-z]")}'	#小写字母在第2个位置开始出现
2

tolower(srt)

可以将字符串转换为小写

[14:49:51][root@localhost:~]# awk 'BEGIN{print tolower("HELLo")}'
hello

toupper(str)

将字符串转为大写

split(字符串,数组,分隔符)

将字符串按特定的分隔符切片后存储在数组中,如果没指定分隔符,则使用IFS定义的。
数组下标从1开始

awk 'BEGIN{split("hello world",test); print test[1],test[2]}'
awk 'BEGIN{split("hello:world",test,":"); print test[1],test[2]}'	#指定冒号(:)为分隔符

在这里插入图片描述

gsub(r,t])

将字符串t中所有与正则表达式r匹配的字符串全部替换为s,如果没有指定字符串t,则默认对$0进行替换操作

[15:11:47][root@localhost:~]# head -1 /etc/passwd | awk '{gsub("[0-9]","**");print $0}'
root:x:**:**:root:/root:/bin/bash

sub(r,t])

与gsub类似,但仅替换第一个匹配的字符串,而不是替换全部

substr(s,n])

对字符串s进行截取,从第i位开始,截取n个字符串,如果n没有指定则一直截取到字符串s的末尾位置

[15:16:17][root@localhost:~]# awk 'BEGIN{hi="Hello World"; print substr(hi,2,3)}'	#从第2位开始截取3个字符
ell

5.4.内置时间函数

systime()
返回当前时间距离1970-01-01 00:00:00有多少秒

[15:16:21][root@localhost:~]# awk 'BEGIN{print systime()}'
1627802328

5.5.用户自定义函数

语法:

function 函数名(参数列表) { 命令序列 }
awk ' \
function max(x,y) { \
if(x>y) {print x} \
else {print y} } \
BEGIN {max(5,6)} '

在这里插入图片描述

六、常用命令

cat example.txt | awk 'NR%2==1' 	#删除example.txt文件中的所有偶数行
echo "    false" |awk -F' ' '{print $NF}'		#去掉前面的空格
docker images | grep 'mysql' | awk '{printf"%s:%s\n",$1,$2}'	#获取镜像名:Tag
ps -ef | grep java | grep -v 'color' awk '{for (i=8;i<=NF;i++)printf("%s ",$i);print ""}' #获取从第八列开始到最后一列的内容

七、常用技巧

打印各磁盘可用大小

df | grep -v tmpfs | awk 'NR!=1 {disk[$1]=$4} \
END {for(i in disk) {printf "%-20s %-10s\n",disk[i]/1024"M"}
}'

在这里插入图片描述

统计磁盘可用容量

df | tail -n +2 | grep -v tmpfs | awk '{sum+=$4} END{print "磁盘可用容量:"sum/1024/1024"G"}'

在这里插入图片描述

统计/etc下文件总大小

ls -l /etc | awk '/^-/{sum+=$5} END{print "文件总大小:"sum/1024"M"}'

在这里插入图片描述

统计访问Nginx的各IP访问次数

awk ' \
{IP[$1]++} \
END { \
for (i in IP) {print i,IP[i]} \
}' /var/log/nginx/access.log

查看Nginx 1点到5点半的日志

awk -F"[: /]" '$7":"$8 >= "01:00" && $7":"$8 <="05:30"' /var/log/nginx/access.log

查看Docker容器的CPU使用率

docker stats jenkins --no-stream |awk 'NR==2{print $3}'

原文地址:https://anqixiang.blog.csdn.net

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


文章浏览阅读3.7k次,点赞2次,收藏5次。Nginx学习笔记一、Nginx 简介1. 什么是Nginx2. 反向代理3. 负载均衡4. 动静分离二、Nginx基本使用1. Nginx常用的操作命令2. Nginx的配置文件提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档文章目录一、Nginx 简介1. 什么是Nginx2. 反向代理3. 负载均衡4. 动静分离二、Nginx基本使用1. Nginx常用的操作命令2. Nginx的配置文件一、Nginx 简介1. 什么是Nginx  Nginx(“engine x”)是一个_nginx代理
文章浏览阅读1.7w次,点赞14次,收藏61次。我们在使用容器的过程中需,有时候需要对容器中的文件进行修改管理,如果不做文件映射的化,我们使用docker exec -it 容器ID/容器名 /bin/bash 才能进入nginx中的文件里面如图。架设在客户机与目标主机之间,只用于代理内部网络对Internet的连接请求,客户机必须指定代理服务器,并将原本要直接发送到web服务器上的http请求发送到代理服务器中。A想要组C的房子,但是A并不认识C所以租不到,但是B认识C,A找B帮忙租到了C的房子。客户端代理服务器服务器。_docker nginx 配置
文章浏览阅读1.4k次。当用户在访问网站的过程中遇到404错误时,通常情况下应该显示一个友好的错误页面,而不是仅仅显示一个简单的错误提示。在Nginx中,可以通过配置来实现404错误自动跳转到首页的功能。如果您的网站使用动态内容生成页面(如PHP或其他服务器端语言),则应相应地修改配置以适应您的网站架构。这样,当用户访问一个不存在的页面时,Nginx会自动将其重定向到首页。为了使配置生效,需要重新加载Nginx配置。首先,需要打开Nginx的配置文件。现在,当用户访问一个不存在的页面时,Nginx会自动将其重定向到首页。_nginx 404 重定向
文章浏览阅读2.7k次。docker 和 docker-compose 部署 nginx+mysql+wordpress 实战_docker wordpress mariadb
文章浏览阅读1.3k次。5:再次启动nginx,可以正常启动,可以在任务管理器中查看到nginx的进程。重新启动下 直接访问8090端口 ok 访问成功。1 :查看80端口占用情况,pid的值为3960。3:在运行中输入regedit打开注册表编辑器。2: 通过以下命令查看3960所对应的服务名称。4:找到Start,右键修改将其制改为4。_nginx80端口无法访问
文章浏览阅读3.1w次,点赞105次,收藏182次。高性能:Nginx 被设计为能够处理大量并发连接而不显著增加系统负担。它采用异步事件驱动的架构,可以有效地处理高流量的 Web 请求。负载均衡:Nginx 支持负载均衡,可以将请求分发到多个后端服务器,以提高网站性能和可用性。反向代理:Nginx 可以充当反向代理,将客户端请求转发到后端服务器,隐藏后端服务器的真实 IP 地址,增加安全性和可扩展性。静态文件服务:Nginx 可以高效地提供静态文件(如 HTML、CSS、JavaScript、图像等)的服务,减轻应用服务器的负担。
文章浏览阅读976次。nginx作为常用的web代理服务器,某些场景下对于性能要求还是蛮高的,所以本片文章会基于操作系统调度以及网络通信两个角度来讨论一下Nginx性能的优化思路。我们的大学教程大部分讲述七层模型,实际上现代网络协议使用的都是四层模型,如下图,应用层报文经过四层的首部封装到对端。对端链路层拆开首部查看mac地址是自己在网上,拆开ip首部查看目的地址是不是自己,然后到达传输层应用层完成报文接收。文章是基于原有个人知识基础上,对旧知识进行巩固,以及新知识实践学习。
文章浏览阅读5.4k次,点赞9次,收藏15次。最后再说一种情况,就是后端处理了跨域,就不需要自己在处理了(这里吐槽下,某些后端工程师自己改服务端代码解决跨域,但是又不理解其中原理,网上随便找段代码黏贴,导致响应信息可能处理不完全,如method没添加全,headers没加到点上,自己用的那个可能复制过来的并不包含实际项目所用到的,没有添加options请求返回状态码等,导致Nginx再用通用的配置就会可能报以下异常)里面的就好了,因为这里如果是预检请求直接就ruturn了,请求不会再转发到59200服务,如果也删除了,就会报和情况1一样的错误。_nginx 允许跨域
文章浏览阅读2.5k次。项目配置了多个域名,如下,php 代码中有获取的值。当访问a.demo.com时,其获取的值是符合预期的。但是当访问b.demo.com时,其获取的值还是a.demo.com,导致代码中的判断出现错误。_nginxservername多个域名
文章浏览阅读1k次,点赞2次,收藏5次。采用YAML manifest的方式来安装ingress-nginx,用registry.lank8s.cn镜像库来替换 registry.k8s.io的库。_ingress-nginx安装
文章浏览阅读1.6k次,点赞2次,收藏2次。在windows平台编译nginx_windows 编译nginx
文章浏览阅读5.8k次,点赞2次,收藏18次。nginx [engine x] 是 HTTP 和反向代理服务器、邮件代理服务器和通用 TCP/UDP 代理服务器。nginx 的特点是占有内存少,并发能力强,事实上 nginx 的并发能力确实在同类型的网页服务器中表现较好,中国大陆使用nginx网站用户有:百度、京东、新浪、网易、腾讯、淘宝等。在高连接并发的情况下,nginx是Apache服务器不错的替代品,能够支持高达50000个并发连接数的响应。使用epoll and kqueue作为开发模型。_nginx
文章浏览阅读2k次。Linux启动(systemctl start nginx)nginx服务时出现:Failed to start nginx.service: Unit not found._为什么nginx的systemctl start nginx.service不能使用
文章浏览阅读1.3k次。重启之后,打开浏览器,输入http://localhost:8900/myBaidu,这时候就会自动的跳转到百度的页面。按照我们不同的需求修改nginx文件夹中的nginx-1.16.1conf里面的nginx.conf文件。启动nginx:打开nginx的文件夹,然后双击nginx.exe文件,启动nginx。打开之后假设我们需要跳转到百度则在配置文件nginx.conf中的下面加上。1、打开任务管理器关闭nginx的进程。端口在配置文件的(下图)进行查看nginx端口。_nginx 代理百度
文章浏览阅读5.7k次,点赞5次,收藏3次。nginx重定向问题解决(rewrite or internal redirection cycle)_rewrite or internal redirection cycle while internally redirecting to "/inde
文章浏览阅读1.3k次。请注意,上述命令假设 Nginx 已经在系统的 PATH 环境变量中配置。如果没有,请提供正确的 Nginx 安装路径,或者在命令中使用完整的路径来替换。将该命令与所有 Nginx 进程的 PID 一起使用,以终止所有正在运行的 Nginx 进程。此命令将启动一个新的 Nginx 进程来重新加载配置文件并重新启动服务器。使用以下命令来终止所有 Nginx 进程(使用上面的 PID 替换。的进程以及它们的 PID。打开命令提示符(CMD)。此命令将列出所有名为。选项来强制终止进程。_windows 怎么关闭nginx
文章浏览阅读2.7k次,点赞2次,收藏7次。包括 Netflix、GitHub 和 WordPress。Nginx 可以用作 Web 服务器、负载均衡器、反向代理和 HTTP 缓存等。_ubuntu安装nginx
文章浏览阅读915次。轻松搭建短域名短链接服务系统,可选权限认证,并自动生成证书认证把nginx的http访问转换为https加密访问,完整步骤和代码。_nginx 短链代理
文章浏览阅读1.1k次,点赞35次,收藏24次。流媒体方案之Nginx——实现物联网视频监控项目Nginx是什么Nginx在流媒体方案中的位置软硬件准备移植编译Nginx运行Ngnix测试流媒体方案浏览器播放_nginx-rtmp-module
文章浏览阅读1.9k次。nginx 配置 wss 协议转发 ws 服务器_nginx 配置wss