十五、shell编程三剑客(4)awk
1.简介
awk是一种编程语言,用于在linux/unix下对文本和数据进行处理。数据可以来自标准输入、一个或多个文件,其他命令的或命令的输出。它支持用户自定义函数和动态正则表达式等先进功能。
awk的处理文本和数据方式是逐行处理,从第一行到最后一行。寻找匹配的特定模式的行,并在这些行上进行你想要的操作。如果没有指定处理动作,则把匹配的行显示到标准输出(屏幕)。
2.工作原理
(1)awk 使用一行作为输出,并将这一行赋值给内部变量$0,每一行也可以称为一个记录,以换行符结束
(2)然后,行被:(默认为空格或者制表符)分解成字段(或域),每一个字段储存在对应的编号的变量中,从$1开始,最多100个字段
(3)awk输出之后,将从文件中获取另一行,并将其存储在$0中,覆盖原来的内容,然后将新的字符串分割成字段并进行处理,该过程将持续到所有行处理完毕。
自定义分隔符
awk -F: '{print $1,$5}' /erc/passwd | head -3
3.语法
awk 选项 '命令' 文件名
command(命令):
分为过去,现在,将来
BEGIN{} {} END{}
BEGIN{}:发生在行处理之前
{}:行处理时,读一行执行一次
END{}:行处理后
4.内部变量
FS 输入字段分隔符(默认空格)
在开始之前把:赋值给FS,FS即使内部变量
OFS 输出字段分隔符
重新给结果分割
RS 输入记录(行)分隔符,默认换行符,就是行与行之间的分隔符(了解)
把空格当成分隔符
ORS 输出记录(行)分隔符,默认换行符
FNR 多文件独立编号 同下
NR 多文件汇总编号
NF 显示列
如果$NF等于输出最后一列,因为这里等于print $5
5.格式化输出print
6.模式(正则表达)和动作
字符串比较
awk '/^root/' /etc/passwd 以root开头的那行
awk '$0 - /^root/' /etc/passwd 像是以root开头的
awk '$0 !~ /^root/passwd' 不像是以root开头的
awk -F: '$1 ~ /^root/' /etc/passwd 在第一行中像是以root开头的
关系运算符
语法 x>y
awk -F: '$3>5' /etc/passwd
awk -F: '$3 == 3' /etc/passwd
awk -F: '$3*10 < 100' /etc/passwd
多条件-逻辑操作符和复合模式
与 &&
awk -F: '$1 ~ /root/ && $3<=5' /etc/passwd
或 ||
awk -F: '$1 ~ /root/ || $3<=5' /etc/passwd
非 !
多条件-范围模式
awk '/从哪里/,/到哪里/' filename
例子
awk -F: '/adm/,/mail/' /etc/passwd 从adm那行到mail那行显示出来,注意避免匹配重复的字段
7.awk脚本编程
变量
awk调用变量
awk -v user=root -F: '$1 == user' /etc/passwd -v定义变量
外部变量
因为$name不是内部变量,需要用''括起来,但是单引号里面套单引号是有问题的,所以要用""双引号套起来
条件&判断
if语句
if(条件测试){执行语句}
示例1
需求:如果$3是0,就说他是管理员
awk -F: '{if($3==0){print $1 "是管理员"}}' /etc/passwd
awk -F: '{if($3==0){print $1 "是管理员"}else{print $1 "是普通用户"}}' /etc/passwd
示例2
需求:统计管理员和系统用户的数量
awk -F: '{if($3==0){r++}else{u++}}END{print "管理员个数:"r;print"系统用户数:"u}' /etc/passwd
示例3
统计三种用户的数量
显示出三种用户信息,管理员:管理员ID为0,内置用户:用户ID<1000,普通用户:用户ID>999
awk -F: '{if($3==0){a++}else if($3>999){b++}else{c++}}END{print "管理员:"a;print "内置用户:"b;print "普通用户:"c}' /etc/passwd
awk -F: '{if($3==0){print $1 "是管理员"}else if($3>999){print $1 "是内置用户"}else{print $1 "是普通用户"}}' /etc/passwd
循环
示例1:循环打印10个数字
awk 'BEGIN{while(){}}'
示例2:第一行打印十次
awk -F: '{while(i<=9){print $0;i++}}' passwd
for
示例1:循环打印5个数字
awk 'BEGIN{for(i=1;i<=5;i++){print i}}'
示例2:将每行打印10次
awk -F: '{for(i=1;i<=10;i++){print $0}}' passwd
示例3:打印每一行的第一列
awk -F: '{for(i=1;i<=NF;i++){print $1}}' passwd
数组
定义数组
需求:将用户名定义为数组的值,打印第一个值
awk -F: '{username[i++]=$1}END{print username[0]}' passwd
打印所有值
awk默认不排序,填上索引再以数字排序就行
8.awk编程案例
需求:统计/etc/passwd中各种类型shell的数量
awk -F: '{shellname[$NF]++}END{for(i in shellname){print i "有" shellname[i] "个"}}' /etc/passwd
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 2025年我用 Compose 写了一个 Todo App
· 张高兴的大模型开发实战:(一)使用 Selenium 进行网页爬虫