Linux之awk

AWK#

概念#

  • Awk是一种文本处理工具
  • Awk是目前Linux与Unix强大的数据处理引擎之一

语法组成方式#

任何AWK语法都是由模式与动作组成 一个AWK脚本可以有多个语句 模式决定动作语句的触发动作与时间

Copy
# 模式 正则表达式 : /root/ 匹配含有 root 的行 /*.root/ 关系表达式: < > && || + * 匹配表达式: ~ ! ~ # 动作 变量 命令 内置函数 流控制语句

AWK执行步骤#

  • 读取:从文件 管道 标准输出读取数据存放到内存中
  • 执行:将读取的内容按照Body体内的内容执行相应的动作
  • 重复:重复上述动作直到数据全部读取完成

内置变量(预定义变量)#

$n#

当前记录的第n个字段 例如:$1记录的第一个字段 $2记录的第二个字段

Copy
[root@SR ~]# cat data.txt | awk '{printf $1 "\t" $2 "\n"}'

$0#

包含执行过程中当前行的文本内容

Copy
[root@SR ~]# cat data.txt | awk '{printf $0 "\n"}'

FS#

文件的分隔符(默认是空格进行分割)

Copy
[root@SR ~]# cat passwd | awk 'BEGIN{FS=":"} {printf $1 "\t" $3 "\n"}' | head -1

NF#

代表的是一个文本文件中一行(一条记录)中的字段个数

Copy
[root@SR ~]# awk '{print "字段数:" NF}' data.txt

NR#

代表当前文本的行数 例如:NR==2表示第二行

Copy
[root@SR ~]# cat -n data.txt | awk '{printf "当前行数:" "\n" NR}' data.txt

FNR#

各文件分别计数的行号

OFS#

输出字段分隔符(默认是一个空格)

ORS#

输出记录分隔符(默认值是一个换行符)

RS#

记录分割符(默认是一个换行符)

AWK常见使用方式#

分隔符使用#

-F/fs 其中 fs 是指定输入分隔符, fs 可以是字符串或正则表达式;分隔符默认是空格

Copy
[root@SR ~]# echo "AA BB CC DD" | awk -F " " '{printf $2 "\t" "\n"}'

Copy
[root@SR ~]# echo "AA|BB|CC|DD" | awk -F "|" '{print $1 }'

Copy
[root@SR ~]# echo "12AxAbADXaAD52" | awk 'BEGIN {FS="aA"} {print $2}'

Copy
# 过滤IP地址 [root@SR ~]# ifconfig ens160 | grep netmask | awk '{print $2}'

关系运算符#

Copy
[root@SR ~]# echo "1 2 3 4 5" | awk '{print $1 +10}'

Copy
[root@SR ~]# echo "1 2 3 4" | awk '{print $NF}'

Copy
# 打印 uid < 10的用户名以及shell解释器 [root@SR ~]# cat passwd | awk -F ":" '$3 < 10 {printf $1 "\t" $NF "\n"}' | head -1

Copy
# 打印UID大于等于1000的用户名以及shell解释器 [root@SR ~]# cat passwd | awk -F ":" ' $3 >= 1000 && $NF== "/bin/bash" {printf $1 "\t" $NF "\n"}'

脚本使用#

Copy
# 统计内存使用频率 [root@SR ~]# cat mem.sh #!/bin/bash mem_user=`free -m | grep -i mem | awk '{print $3/$2*100"%"}'` echo -e "内存使用百分比为>>: \e[31m${mem_user}\e[0m"

AWK的高级应用#

awk模式#

empty#

regular expression#

仅仅处理能够被当前匹配的行数

Copy
# 匹配以root开头的 [root@SR ~]# cat passwd | awk -F ":" '/^root/{print$0}'

范围匹配#

Copy
# 输出行号大于等于 3 且行号小于等于 6 的行 [root@SR ~]# cat passwd | awk -F ":" 'NR>=3&&NR<=6 {printf NR ":" $1 "\t" $NF "\n"}'

内置变量#

Copy
$0 表示整个当前行 NF 字段数量 NF(Number 数量 ; field 字段) NR 每行的记录号,多文件记录递增 Record [?rek?:d] \t 制表符 \n 换行符 ~ 匹配 !~ 不匹配 -F'[:#/]+' 定义三个分隔符

NR#

表示当前行号

Copy
使用NR过滤IP地址 [root@SR ~]# ifconfig ens160 | awk -F " " 'NR==2 {print $2}'

FNR#

Copy
[root@SR ~]# awk '{print FNR"\t" $0}' /etc/hosts /etc/hostname

  • 对于NR来说读取不同的文件时候 NR是一直增加的
  • 对于FNR来说读取不同的文件时候 FNR值会从1开始进行计算

!~#

Copy
# 匹配出不是第一行内容 [root@SR ~]# cat passwd | awk -F ":" 'NR !=1 {print "当前行数" NR ":" $0}' | head -1

条件表达式#

if-true/if-false#

Copy
# 类似于Python的三元表达式 ?前面为真则执行?后面的语句 否则执行:后面的语句 [root@SR ~]# cat passwd | awk -F ":" '{ $3<10?test="UID小于10":test="UID大于10";print $1":" test}' | head -5

if(条件){命令}/elif(条件){命令}/else#

Copy
# 如果 UID 小于 5 ,则输出 小于5用户名,否则输出 大于5用户名 [root@SR ~]# cat passwd | awk -F ":" '{if($3 <5 ){print "UID小于5用户名称>>:" $1} else {print "UID大于5用户名称>>:" $1}}' | head -10

变量#

Copy
[root@SR ~]# var="test" [root@SR ~]# awk 'BEGIN{print "'$var'"}'

修饰符#

  • N:显示宽度
  • -:进行左对齐
  • 一个字母占一个宽度 默认是右对齐
Copy
# 显示时用 10 个字符串右对齐显示如果要显示的字符串不够 10 个宽度,以字符串的左边自动添加一个字母占一个宽度 默认是右对齐 [root@SR ~]# cat passwd | awk -F ":" '{printf "%10s\n" , $1}' | head -5

Copy
# 第 1 列使用 15 个字符宽度左对齐输出,最后一列使用 15 个字符宽度右对齐输出 [root@SR ~]# cat passwd | awk -F ":" '{printf "用户名:%-15s shell类型:%15s\n" , $1, $NF}' | head -2

posted @   SR丶  阅读(165)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
点击右上角即可分享
微信分享提示
CONTENTS