AWK Programing Language | 史上最全 awk 一本通

news2025/1/13 3:34:15

在这里插入图片描述

博客原文

文章目录

    • awk 工作模式
    • 语法格式
    • 内置变量
    • 格式化输出 printf
    • 模式匹配
    • awk 算数运算
    • 条件语句
    • 循环语句
    • 字符串函数
    • awk 常用选项
    • awk 与 shell 中数组
      • shell 中数组
      • awk 中数组
    • 脚本练习

awk 工作模式

与 sed 相同, 都是逐行处理

语法格式

  1. awk ‘BEGIN{}pattern{commands}END{} filename’
  2. stdout | awk ‘BEGIN{}pattern{commands}END{}’
语法格式说明
BEGIN{}处理文本前执行
pattern匹配模式
{commands}处理命令, ;隔开
END{}处理文本后执行

BEGIN{}, pattern, END{} 多可省略

内置变量

内置变量含义
$0整行内容
1 − 1- 1n按分隔符的第 1-n 个字段
NF (Number Field)当前行的字段个数(多少列)
NR (Number Row)当前行行号, 从 1 开始计数
FNR (File Number Row)多文件处理时, 每个文件单独技术, 从 1 开始
FS (Field Separate)输入字段分隔符, 不指定为空格或 tab
RS (Row Separator)输入行分隔符, 默认回车
OFS (Output Field Separator)输出字段分隔符
ORS (Output Row Separator)输出行分隔符, 默认回车
FILENAME当前输入文件名
ARGC命令行参数个数
ARGV命令行参数数组

基本使用:


$ awk '{print $0}' passwd
$ awk '{print $1,$3}' list
$ awk '{print NF}' list
$ awk '{print NR}' list
$ awk '{print FNR}' list awk.txt

$ awk 'BEGIN{FS=":"}{print $1}' passwd
$ awk 'BEGIN{RS="--"}{print $0}' list
$ awk 'BEGIN{FS=":";OFS="|"}{print $1,$3}' passwd  # 每行输出字段
$ awk 'BEGIN{ORS="--"}{print $0}' passwd

$ awk '{print FILENAME}' passwd
$ awk '{print ARGC}' passwd list  # 3 个参数 awk, passwd, list

格式化输出 printf

格式符含义
%s字符串
%d十进制
%f浮点数
%x十六进制
%o八进制
%e科学计数法
%c单个字符

修饰符:

修饰符含义
-左对齐
+右对齐
#打印 十六进制与八进制时使用, 在前打印进制标识

示例

# %s: 默认左对齐
# %10s: 默认右对齐
$ awk 'BEGIN{FS=":"}{printf "%s",$7}' passwd
$ awk 'BEGIN{FS=":"}{printf "%10s",$7}' passwd
$ awk 'BEGIN{FS=":"}{printf "%-10s",$7}' passwd

$ awk 'BEGIN{FS=":"}{printf "%d",$3}' passwd
$ awk 'BEGIN{FS=":"}{printf "%0.3f",$3}' passwd
$ awk 'BEGIN{FS=":"}{printf "%x",$3}' passwd
$ awk 'BEGIN{FS=":"}{printf "%#x",$3}' passwd  # 显示 16 进制标识
$ awk 'BEGIN{FS=":"}{printf "%0",$3}' passwd
$ awk 'BEGIN{FS=":"}{printf "%e",$3}' passwd

模式匹配

  1. 正则表达式 (固定写法//)
  2. 关系运算匹配

正则表达式:****

# 含有 root 的行
$ awk 'BEGIN{FS=':'}/root/{print $0}' passwd
# 以 nginx 开头
$ awk 'BEGIN{FS=':'}/^nginx/{print $0}' passwd

关系运算符:

关系运算符含义
< 数值小于
> 数值大于
<= 数值小于等于
>= 数值大于等于
==等于
!=不等于
~匹配正则
!~不匹配正则
# 第 3 个字段小于 50
$ awk 'BEGIN{FS=":"}$3<50{print $0}' passwd

# 第 7 个字段为 /bin/bash
$ awk 'BEGIN{FS=":"}$7=="/bin/bash"{print $0}' passwd
$ awk 'BEGIN{FS=":"}$7!="/bin/bash"{print $0}' passwd

# 第 3 个字段包含 3 个及以上数字
$ awk 'BEGIN{FS=":"}$3~/[0-9]{3,}/{print $0}' passwd

逻辑运算符:

逻辑运算符含义
||
&&
!
$ awk 'BEGIN{FS=":"}$1=="root"||$1=="nginx"{print $0}' passwd

$ awk 'BEGIN{FS=":"}$3<50 && $3 >30 {print $0}' passwd

awk 算数运算

运算符含义
+
-
*
/
%取余
^ 或 **乘方
x++ ; x–先返回 x, 后 +/- x
++x ; --x先 +/- x, 后 返回 x

练习计算课程平均值

# 右对齐
$ awk 'BEGIN{printf "%10s%10s%10s%10s%10s\n","Name", "YuWen","ShuXue", "English", "AVG"}{total=$1+$2+$3;AVG=total/3;printf "%10s%10d%10d%10d%10.2f\n",$1,$2,$3,$4,AVG}' list

$ awk 'BEGIN{printf "%-10s%-10s%-10s%-10s%-10s\n","Name", "YuWen","ShuXue", "English", "AVG"}{total=$1+$2+$3;AVG=total/3;printf "%-10s%-10d%-10d%-10d%-10.2f\n",$1,$2,$3,$4,AVG}' list

条件语句

if-else

示例: script.awk

BEGIN{
	FS=":"
}

{
	if($3<50)
	{
		printf "%-20s%-10s%10d\n","UID<50",$1,$3
	}
	else if($3>50 && $3 <100)
	{
		printf "%-20s%-10s%10d\n","50<UID<100",$1,$3
	}
	else
	{
		printf "%-20s%-10s%10d\n","UID>100",$1,$3
	}
}
$ awk -f script.awk /etc/passwd

循环语句

  1. do-while
  2. while
  3. for

计算 1+2+…100

  1. do-while
BEGIN{

    do{
        sum += i
        i++
    }while(i<=100)

    print sum
}
  1. while
BEGIN{
    while(i<=100)
    {
        sum += i
        i++
    }
    print sum
}
  1. for
BEGIN{
    for(i=0;i<=100;i++)
    {
        sum += i
    }

    print sum
}

练习: 打印平均分大于 70的, 并计算平均分

BEGIN{
    printf "%-10s%-10s%-10s%-10s%-10s\n","Name","YuWen","Math","English","AVG"
}

{
    total = $2 + $3 + $3
    avg = total / 3
    if (avg > 70)
    {
        printf "%-10s%-10d%-10d%-10d%-0.2f\n",$1,$2,$3,$4,avg
        score_yuwen += $2
        score_math += $3
        score_english += $4
        score_avg += avg
        count++
    }

}

END{
    printf "%-10s%-10.2f%-10.2f%-10.2f%-0.2f\n","",score_yuwen/count,score_math/count,score_english/count,score_avg/count
}

字符串函数

函数名解释返回值
length(str)计算字符串长度长度值
index(str1,str2)在 str1 中查找 str2返回位置索引, 从 1 计数
tolower(str)转小写转小写后的字符串
toupper(str)转大写转大写后的字符串
substr(str,m,n)从 str m 字符, 截取 n 位(n 可省略)截取后的子串
split(str,arr,fs)按 fs 切割字符串, 结果保存到 arr切割后的子串个数
match(str,RE)与 index() 类似, 但支持正则(RE)返回索引位置
sub(RE,RepStr,str)在 str 中搜索符合 RE 的子串将其替换为 RepStr; 只替换第一个替换个数
gsub(RE,RepStr,str)在 str 中搜索符合 RE 的子串将其替换为 RepStr; 替换全部替换个数

1. 打印 passwd 每个字段长度:

BEGIN{
    FS=":"
}

{
    i=1
    while(i<=NF)
    {
        if(i==NF)
            printf "%d",length($i)
        else
            printf "%d:",length($i)
        i++
    }
    print ""
}

2. 查询"I have a dream"中"ea"索引

$ awk 'BEGIN{str="I have a dream";localtion=index(str,"ea");print localtion}'
# 12
$ awk 'BEGIN{str="I have a dream";localtion=match(str,"ea");print localtion}'
# 12

3. 大小写转换

$ awk 'BEGIN{str="I have a dream";print tolower(str)}'
# i have a dream
$ awk 'BEGIN{str="I have a dream";print toupper(str)}'
# I HAVE A DREAM

4. 切分数组

$ awk 'BEGIN{str="I have a dream";split(str,arr," ");print arr[2]}'
$ awk 'BEGIN{str="I have a dream";split(str,arr);print arr[2]}'  # 默认空格分隔
# have

# 遍历, 不是顺序遍历
$ awk 'BEGIN{str="I have a dream";split(str,arr);for(a in arr) print arr[a]}'
# dream
# I
# have
# a

5. 搜索第一个出现的数字

# 正则必须用 //
$ awk 'BEGIN{str="I have a 123 dream"; print match(str, /[0-9]/)}'
# 10

6. 截取子串

$ awk 'BEGIN{str="I have a 123 dream"; print substr(str,3,7)}'
# have a 

$ awk 'BEGIN{str="I have a 123 dream"; print substr(str,3)}'
# have a 123 dream

7. 替换数字

$ awk 'BEGIN{str="I have a 123 dream 324 hello"; print sub(/[0-9]+/,"$",str); print str}'
# 1
# I have a $ dream 324 hello

$ awk 'BEGIN{str="I have a 123 dream 324 hello"; print gsub(/[0-9]+/,"$",str); print str}'
# 2
# I have a $ dream $ hello

awk 常用选项

选项说明
-v参数传递
-f指定脚本文件
-F指定分隔符
-V查看版本

如果变量有空格, 要使用""

$ num=13
$ var="hello world"
$ awk -v num1=$num -v var1=$var 'BEGIN{print num1,var1}'
# awk: fatal: cannot open file `BEGIN{print num1,var1}' for reading (No such file or directory)

$ awk -v num1="$num" -v var1="$var" 'BEGIN{print num1,var1}'
# 13 hello world


$ awk -F ":" '{print $0}' /etc/passwd

awk 与 shell 中数组

shell 中数组

下标从 0 开始

打印数组:

$ arr=("kubernetes" "etcd" "time" "redis")

# 打印数组
$ echo ${arr[@]}
$ echo ${arr[*]}
# kubernetes etcd time redis

# 打印元素
$ echo ${arr[2]}
# time

打印数组/元素长度; 分片访问; 元素操作; 删除元素:

$ arr=("kubernetes" "etcd" "time" "redis")

# 打印数组
$ echo ${#arr[@]}
$ echo ${#arr[*]}
# 4

# 打印元素
$ echo ${#arr[3]}
# 5

# 分片访问
$ echo ${arr[@]:1:3}
# etcd time redis

# 元素赋值
$ arr[2]=mysqlserver
$ echo ${arr[@]}
# kubernetes etcd mysqlserver redis

# 元素内容替换
$ echo ${arr[@]/e/E}
# kubErnetes Etcd mysqlsErver rEdis
$ echo ${arr[@]//e/E}
# kubErnEtEs Etcd mysqlsErvEr rEdis

# 元素删除  *** 通过下标删除后, 被删除的下标的元素为空, 原数组的其他元素下标不变
$ unset arr[0]
$ echo ${arr[@]}
# etcd mysqlserver redis
$ unset arr[0]
$ echo ${arr[@]}
# etcd mysqlserver redis
$ unset arr[1]
$ echo ${arr[@]}
# mysqlserver redis

# 删除数组
$ unset arr

通过下标删除后, 被删除的下标的元素为空, 原数组的其他元素下标不变

数组的遍历

$ arr=("kubernetes" "etcd" "time" "redis")
$ for a in ${arr[@]}; do echo $a; done
# kubernetes
# etcd
# time
# redis

awk 中数组

脚本练习

数据生成脚本:

#!/bin/bash
#

function create_random()
{
    min=$1
    max=$(($2-$min+1))
    num=$(date +%s%N)
    echo $(($num%$max+min))
}

INDEX=1

while true
do
    for user in allen mike jerry tracy han lilei
    do
        COUNT=$RANDOM
        NUM1=`create_random 1 $COUNT`
        NUM2=`expr $COUNT - $NUM1`
        echo "`date '+%Y-%m-%d %H:%M:%S'` $INDEX Batches: user $user insert $COUNT records into database:product table:detail, insert $NUM1 records successfully, failed $NUM2 records" >> ./db.log.`date +%Y%m%d`
        INDEX=`expr $INDEX + 1`
    done
done

数据格式

2023-12-12 02:49:31 1 Batches: user allen insert 25719 records into database:product table:detail, insert 24482 records successfully, failed 1237 records
2023-12-12 02:49:31 2 Batches: user mike insert 32653 records into database:product table:detail, insert 26055 records successfully, failed 6598 records
2023-12-12 02:49:31 3 Batches: user jerry insert 16986 records into database:product table:detail, insert 11636 records successfully, failed 5350 records
2023-12-12 02:49:31 4 Batches: user tracy insert 31899 records into database:product table:detail, insert 9250 records successfully, failed 22649 records
2023-12-12 02:49:31 5 Batches: user han insert 24256 records into database:product table:detail, insert 24033 records successfully, failed 223 records

统计所有成功, 失败, 总共记录数

count.awk:

BEGIN{
    printf "%-10s%-20s%-20s%-20s\n","User","Total","Sucess","Failed"
}

{
    TOTAL[$6]+=$8
    SUCESS[$6]+=$14
    FAILED[$6]+=$18
}

END{
    for(t in TOTAL)
    {
        total += TOTAL[t]
        sucess += SUCESS[t]
        failed += FAILED[t]
        printf "%-10s%-20s%-20s%-20s\n",t,TOTAL[t],SUCESS[t],FAILED[t]
    }
    printf "%-10s%-20s%-20s%-20s\n","",total,sucess,failed
}
$ awk -f count.awk db.log.20231212
User      Total               Sucess              Failed
tracy     6096344             2963340             3133004
allen     6293470             3182865             3110605
mike      5845083             2912982             2932101
jerry     5996178             3080723             2915455
lilei     6217104             3028971             3188133
han       5923975             3089899             2834076
          36372154            18258780            18113374

2. 打印丢失记录的行数

一条记录行中, 总记录数 != 成功记录数 + 失败记录数

$ awk '{if($8 != $14 + $18) print NR}' db.log.20231212

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1471111.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

matlab倒立摆小车LQR控制动画

1、内容简介 略 54-可以交流、咨询、答疑 2、内容说明 略 摆杆长度为 L&#xff0c;质量为 m 的单级倒立摆(摆杆的质心在杆的中心处)&#xff0c;小车的质量为 M。在水平方向施加控制力 u&#xff0c;相对参考系产生位移为 y。为了简化问题并且保其实质不变&#xff0c;忽…

[ffmpeg] x264 配置参数解析

背景 创建 x264 编码器后&#xff0c;其有一组默认的编码器配置参数&#xff0c;也可以根据需要修改参数&#xff0c;来满足编码要求。 具体参数 可修改的参数&#xff0c;比较多&#xff0c;这边只列举一些常用的。 获取可以配置的参数 方式1 查看 ffmpeg源码 libx264.c…

【JVM】聊聊JVM生产环境常见的OOM问题

对于JVM来说&#xff0c;因为划分有固定的区域来执行字节码文件&#xff0c;无外乎&#xff0c;出问题的&#xff0c;也就是按照对应分分区会有常见的OOM问题。 栈 对于栈来说&#xff0c;栈的主要作用就是用于方法的执行&#xff0c;方法调用入栈、方法调出出栈。但是如果我…

光伏预测 | Matlab基于CNN-SE-Attention-ITCN的多特征变量光伏预测

光伏预测 | Matlab基于CNN-SE-Attention-ITCN的多特征变量光伏预测 目录 光伏预测 | Matlab基于CNN-SE-Attention-ITCN的多特征变量光伏预测预测效果基本描述模型简介程序设计参考资料 预测效果 基本描述 Matlab基于CNN-SE-Attention-ITCN的多特征变量光伏预测 运行环境: Matla…

数学建模【插值与拟合】

一、插值与拟合简介 在数学建模过程中&#xff0c;通常要处理由试验、测量得到的大量数据或一些过于复杂而不便于计算的函数表达式&#xff0c;针对此情况&#xff0c;很自然的想法就是&#xff0c;构造一个简单的函数作为要考察数据或复杂函数的近似。插值和拟合就可以解决这…

[算法沉淀记录] 排序算法 —— 选择排序

排序算法 —— 选择排序 基本概念 选择排序是一种简单的排序算法&#xff0c;它的工作原理是每次从待排序的列表中选择最小&#xff08;或最大&#xff09;的元素&#xff0c;将其与列表中的第一个位置交换&#xff0c;然后继续对剩余的元素进行排序&#xff0c;直到整个列表…

数据结构2月21日

双向链表: func函数&#xff1a; #include <stdio.h> #include <stdlib.h> …

opengles 绘制图元 ——glDrawArrays() 相关API介绍 (十)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、opengles3.0 绘制图元介绍二、绘图图元 API 介绍1. glDrawArrays()1.1 glDrawArrays()函数原型1.2 GL_TRIANGLES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN 三者的区别1.3 使用GL_TRIANGLES, G…

微信小程序 wxs内联与外联的写法

内联写法 <!-- 内联wxs --> <view>大写字母{{m1.toUpper("xmly")}}</view> <wxs module"m1">module.exports.toUpperfunction(str){return str.toUpperCase()} </wxs> 外联写法 新建一个wxs文件 写一个函数&#xff0c;将…

【k8s】-- 查询 pod 磁盘容量

命令&#xff1a;kubectl get pvc -n 你的namespace --context上下文命名 -o wide 举例&#xff1a;kubectl get pvc -n my-bigdata --contextprod-6 -o wide

HarmonyOS服务卡片开发指导(Stage模型)概述

服务卡片概述 服务卡片&#xff08;以下简称“卡片”&#xff09;是一种界面展示形式&#xff0c;可以将应用的重要信息或操作前置到卡片&#xff0c;以达到服务直达、减少体验层级的目的。卡片常用于嵌入到其他应用&#xff08;当前卡片使用方只支持系统应用&#xff0c;如桌…

多输入分类|WOA-CNN|鲸鱼算法优化的卷积神经网络分类预测(Matlab)

目录 一、程序及算法内容介绍&#xff1a; 基本内容&#xff1a; 亮点与优势&#xff1a; 二、实际运行效果&#xff1a; 三、部分程序&#xff1a; 四、完整程序数据下载&#xff1a; 一、程序及算法内容介绍&#xff1a; 基本内容&#xff1a; 本代码基于Matlab平台编译&…

免编程经验,搭建宠物店小程序轻松实现

在如今的互联网时代&#xff0c;小程序商城已成为各行业推广和销售的热门方式。对于花店来说&#xff0c;搭建一个自己的小程序商城不仅可以提升品牌形象&#xff0c;还可以方便顾客在线选购花卉产品。下面就来教大家如何轻松搭建一个花店小程序商城&#xff0c;并通过引流获得…

WiFi又演进了,这次是WiFi 7

现在很多笔记本laptop、电视TV、手机Phone,甚至车机IVI都有了WiFi和蓝牙BT的接入功能。 不管WiFi、蓝牙BlueTooth、NBIoT、ZigBee等等无线的技术、无线通信模块的技术,其本质都是在无线频谱上以某种频段某种调制方式传输某个协议的数据进行通信,所以通信标准的演进就决定着…

webGL开发的软件项目类型

WebGL&#xff08;Web Graphics Library&#xff09;作为一种强大的JavaScript API&#xff0c;能够在Web浏览器中实现2D和3D图形的渲染&#xff0c;适用于开发多种类型的软件项目。以下是WebGL可以开发的一些软件项目类型&#xff0c;希望对大家有所帮助。北京木奇移动技术有限…

QT GUI编程常用控件学习

1 GUI编程应该学什么 2 QT常用模块结构 QtCore: 包含了核心的非GUI的功能。主要和时间、文件与文件夹、各种数据、流、URLs、mime类文件、进程与线程一起使用 QtGui: 包含了窗口系统、事件处理、2D图像、基本绘画、字体和文字类 QtWidgets: 包含了一些列创建桌面应用的UI元素…

k8s笔记26--快速实现prometheus监控harbor

k8s笔记26--快速实现prometheus监控harbor 简介采集指标&配置grafana面板采集指标配置grafana面板 说明 简介 harbor是当前最流行的开源容器镜像仓库项目&#xff0c;被大量IT团队广泛应用于生产、测试环境的项目中。本文基于Harbor、Prometheus、Grafana介绍快速实现监控…

【大数据】Flink SQL 语法篇(四):Group 聚合、Over 聚合

Flink SQL 语法篇&#xff08;四&#xff09;&#xff1a;Group 聚合、Over 聚合 1.Group 聚合1.1 基础概念1.2 窗口聚合和 Group 聚合1.3 SQL 语义1.4 Group 聚合支持 Grouping sets、Rollup、Cube 2.Over 聚合2.1 时间区间聚合2.2 行数聚合 1.Group 聚合 1.1 基础概念 Grou…

Java学习笔记------多态

什么是多态 同类型的对象&#xff0c;表现出的不同形态 多态的表现形式 父类类型 对象名称子类对象&#xff1b; 多态的前提 有继承关系 有父类引用指向子类对象 有方法重写 多态调用成员的特点 变量调用&#xff1a;编译看左边&#xff0c;运行也看左边 方法调用&am…

力扣LCR 140. 训练计划 II(顺序遍历,快慢指针)

Problem: LCR 140. 训练计划 II 文章目录 题目描述思路复杂度Code 题目描述 思路 思路1&#xff1a;顺序遍历 欲返回倒数第cnt个节点则需要顺序遍历到len-cnt&#xff08;其中len为链表的长度&#xff09; 思路2&#xff1a;快慢指针 让一个快指针fast指向cnt 1个节点&#x…