AWK系统学习指南:从文本处理到数据分析的终极武器 介绍

目录
一、AWK核心设计哲学解析
1.1 记录与字段的原子模型
1.2 模式-动作范式
二、AWK编程语言深度解析
2.1 控制结构
说明:
2.2 关联数组
代码说明:
示例输入和输出:
注意事项:
2.3 内置函数库
三、高级应用技巧
3.1 多文件处理
代码说明:
示例输入和输出:
注意事项:
3.2 进程间通信
代码说明:
示例输出:
改进版本(支持毫秒):
3.3 模块化编程
代码说明:
示例:
注意事项:
改进版本(增加错误处理):
总结:
四、性能优化实践
4.1 正则表达式优化
脚本解释:
示例输入和输出:
注意事项:
4.2 内存管理
4.3 并行处理
命令解释:
附录:AWK版本特性对比
一、AWK核心设计哲学解析
1.1 记录与字段的原子模型
AWK将输入数据视为由记录(Record)和字段(Field)构成的二维结构:
- 记录默认以换行符分隔(RS变量控制)
- 字段默认以空白字符分隔(FS变量控制)
- 内置变量:
$0:完整记录$1~$n:第1到第n个字段NF:当前记录字段总数NR:已处理记录总数
# 示例:显示文件每行的字段数
{print NR, NF}
1.2 模式-动作范式
AWK程序由模式(Pattern)和动作(Action)的配对组成:
pattern { action }
- BEGIN模式:程序开始前执行
- END模式:所有记录处理完毕后执行
- 正则表达式模式:
/regex/ - 范围模式:
pattern1, pattern2
# 示例:统计/etc/passwd中普通用户数量
BEGIN {count=0}
$3 >= 1000 && $3 < 60000 {count++}
END {print "普通用户数量:", count
}
二、AWK编程语言深度解析
2.1 控制结构
说明:
-
条件判断:
if、else if、else语句的代码块都进行了缩进,使结构更清晰。 -
循环结构:
-
for循环的初始条件、循环条件和更新部分都放在一行,代码块进行了缩进。 -
while和do-while循环的代码块也进行了缩进,确保可读性。
-
# 条件判断
if (condition) {statements
} else if (condition) {statements
} else {statements
}# 循环结构
for (i = 0; i < 10; i++) {print(i)
}while (condition) {statements
}do {statements
} while (condition)
2.2 关联数组
AWK的数组本质上是键值对的哈希表:
# 统计词频
{for (i = 1; i <= NF; i++) {words[$i]++}
}END {for (w in words) {print w, words[w] | "sort -nrk2"}
}
代码说明:
-
主循环部分:
-
NF是 AWK 的内置变量,表示当前行的字段数(即单词数)。 -
for (i = 1; i <= NF; i++)遍历每一行的每个单词。 -
words[$i]++将每个单词作为键,值是其出现的次数,存入关联数组words中。
-
-
END 块:
-
END是 AWK 的特殊模式,表示在处理完所有输入行后执行。 -
for (w in words)遍历words数组中的每个单词。 -
print w, words[w]输出单词及其出现次数。 -
| "sort -nrk2"将输出通过管道传递给sort命令,按第二列(出现次数)数值从高到低排序。
-
示例输入和输出:
假设输入文件内容如下:
hello world
hello awk
world is great
运行该 AWK 脚本后,输出结果为:
hello 2
world 2
awk 1
is 1
great 1
注意事项:
-
这段代码假设输入是以空格分隔的文本。
-
如果需要忽略大小写,可以在
words[$i]++之前将单词转换为小写,例如words[tolower($i)]++。 -
如果需要去除标点符号,可以在处理单词时进行额外的过滤。
2.3 内置函数库
| 函数类别 | 典型函数 | 功能说明 |
|---|---|---|
| 字符串处理 | length(), substr(), split() | 字符串操作 |
| 数学运算 | sin(), log(), int() | 数学计算 |
| 时间处理 | systime(), strftime() | 时间转换 |
| I/O操作 | getline(), system() | 输入输出控制 |
| 类型转换 | strtonum(), tolower() | 数据类型转换 |
三、高级应用技巧
3.1 多文件处理
# 处理多个文件时自动重置行号
FILENAME != prevfile {prevfile = FILENAMEFNR = 0
}{print FILENAME, FNR, $0
}
代码说明:
-
FILENAME != prevfile条件:-
FILENAME是 AWK 的内置变量,表示当前正在处理的文件名。 -
prevfile是一个自定义变量,用于存储上一个处理的文件名。 -
当
FILENAME不等于prevfile时,表示切换到新文件,需要重置行号。
-
-
重置行号:
-
prevfile = FILENAME:更新prevfile为当前文件名。 -
FNR = 0:将FNR(当前文件的行号)重置为 0。注意,FNR会在每次读取新行时自动递增,因此这里设置为 0 是为了让下一行的FNR从 1 开始。
-
-
主处理块:
-
print FILENAME, FNR, $0:输出当前文件名、行号和当前行的内容。
-
示例输入和输出:
假设有两个文件:
文件 file1.txt:
Hello
World
文件 file2.txt:
AWK
is
great
运行该 AWK 脚本后,输出结果为:
file1.txt 1 Hello
file1.txt 2 World
file2.txt 1 AWK
file2.txt 2 is
file2.txt 3 great
注意事项:
-
这段代码适用于处理多个文件,且需要在每个文件的行号从 1 开始计数时使用。
-
如果不需要重置行号,可以直接使用
NR(全局行号)而不是FNR。 -
如果文件名中包含空格,建议将
FILENAME用引号括起来,例如print "\"" FILENAME "\"", FNR, $0。
3.2 进程间通信
# 调用系统命令处理数据
BEGIN {cmd = "date +%s"cmd | getline timestampclose(cmd)print "当前时间戳:", timestamp
}
代码说明:
-
BEGIN块:-
BEGIN是 AWK 的特殊模式,表示在处理任何输入行之前执行。 -
在这里,
BEGIN块用于初始化操作。
-
-
获取时间戳:
-
cmd = "date +%s":定义一个命令字符串cmd,用于调用系统命令date +%s,该命令会输出当前的时间戳。 -
cmd | getline timestamp:通过管道将命令cmd的输出传递给getline,并将结果存储在变量timestamp中。 -
close(cmd):关闭命令管道,释放资源。
-
-
输出时间戳:
-
print "当前时间戳:", timestamp:输出当前时间戳。
-
示例输出:
运行该 AWK 脚本后,输出结果类似于:
当前时间戳: 1698765432
注意事项:
-
系统依赖:
-
这段代码依赖于系统的
date命令,因此在 Unix/Linux 系统上可以正常运行,但在 Windows 系统上可能无法直接运行。 -
如果系统中没有
date命令,或者date +%s不支持,脚本会报错。
-
-
时间戳格式:
-
date +%s输出的时间戳是以秒为单位的整数。 -
如果需要毫秒级别的时间戳,可以使用
date +%s%3N(部分系统支持)。
-
-
close(cmd)的作用:-
close(cmd)用于关闭命令管道,避免资源泄漏。如果省略这一步,可能会导致文件描述符耗尽等问题。
-
改进版本(支持毫秒):
如果需要更高精度的时间戳(毫秒),可以修改命令如下:
BEGIN {cmd = "date +%s%3N" # 获取秒和毫秒cmd | getline timestampclose(cmd)print "当前时间戳(毫秒):", timestamp
}
3.3 模块化编程
# 包含外部函数库
@include "awklib.awk" { print format_date($1)
}
代码说明:
-
@include "awklib.awk":-
@include是 GNU AWK 的扩展功能,用于引入外部 AWK 脚本文件。 -
这里引入了名为
awklib.awk的库文件,假设该文件中定义了format_date函数。
-
-
主处理块:
-
{ print format_date($1) }:对每一行的第一个字段($1)调用format_date函数,并输出格式化后的日期。
-
示例:
假设 awklib.awk 文件中定义了以下函数:
# awklib.awk
function format_date(timestamp) {return strftime("%Y-%m-%d %H:%M:%S", timestamp)
}
输入文件内容如下:
1698765432
1698841832
运行该 AWK 脚本后,输出结果为:
2023-10-31 12:37:12
2023-11-01 10:30:32
注意事项:
-
@include的兼容性:-
@include是 GNU AWK 的扩展功能,仅在 GNU AWK(gawk)中支持。如果使用其他 AWK 实现(如mawk或nawk),可能需要手动合并代码或使用其他方式引入库文件。
-
-
format_date函数的实现:-
假设
awklib.awk文件中定义了format_date函数。如果该函数未定义或实现不正确,脚本会报错。 -
如果
format_date函数未定义,可以在脚本中自行实现,例如:function format_date(timestamp) {return strftime("%Y-%m-%d %H:%M:%S", timestamp) }
-
-
输入数据的格式:
-
假设输入文件的每一行第一个字段是一个有效的时间戳(整数)。如果输入数据格式不正确,可能会导致错误。
-
改进版本(增加错误处理):
如果输入数据可能包含无效的时间戳,可以增加错误处理逻辑:
@include "awklib.awk"{if ($1 ~ /^[0-9]+$/) {print format_date($1)} else {print "错误: 无效的时间戳", $1}
}
总结:
-
这段代码的核心是通过
@include引入外部库,并调用库中的函数处理数据。 -
如果
awklib.awk文件或format_date函数未定义,需要确保其存在并正确实现。 -
如果输入数据格式不确定,建议增加错误处理逻辑。
四、性能优化实践
4.1 正则表达式优化
# 邮箱验证脚本详解:避免重复编译正则表达式
BEGIN {email_regex = "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$"
}
$0 ~ email_regex {print "有效邮箱:", $0
}
脚本解释:
-
BEGIN 块:
-
BEGIN { email_regex = "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$" } -
在脚本开始执行之前,定义了一个正则表达式
email_regex,用于匹配有效的电子邮件地址。 -
正则表达式的含义:
-
^[a-zA-Z0-9._%+-]+:匹配邮箱的用户名部分,允许字母、数字、点(.)、下划线(_)、百分号(%)、加号(+)和减号(-)。 -
@:匹配邮箱地址中的@符号。 -
[a-zA-Z0-9.-]+:匹配域名部分,允许字母、数字、点(.)和减号(-)。 -
\.[a-zA-Z]{2,}$:匹配顶级域名(如.com、.org),要求至少两个字母。
-
-
-
主块:
-
$0 ~ email_regex { print "有效邮箱:", $0 } -
对输入的每一行(
$0表示整行内容)进行匹配。 -
如果当前行符合
email_regex正则表达式,则打印"有效邮箱:"和该行的内容。
-
示例输入和输出:
假设输入文件 emails.txt 内容如下:
test@example.com
invalid-email
user.name+tag+sorting@example.com
user@sub.example.com
not-an-email
运行以下命令:
awk -f script.awk emails.txt
输出结果为:
有效邮箱: test@example.com
有效邮箱: user.name+tag+sorting@example.com
有效邮箱: user@sub.example.com
注意事项:
-
正则表达式可能无法覆盖所有合法的电子邮件地址(例如包含国际化域名的邮箱)。
-
如果你需要更复杂的邮箱验证,建议使用专门的库或工具(如 Python 的
email-validator库)。 -
如果输入文件中有空行或格式不正确的行,它们会被忽略。
4.2 内存管理
# 及时清空大数组
{big_array[NR] = $0if (NR % 10000 == 0) {process_data(big_array)delete big_array}
}
- 数据缓存阶段:将每行内容存入数组
big_array,使用行号NR作为索引 - 批处理触发条件:当处理行数是10000的倍数时(第10000、20000...行)
- 数据处理阶段:调用
process_data处理累计的10000行数据 - 内存清理:使用
delete清空数组释放内存
4.3 并行处理
# 使用GNU Parallel配合AWK
find . -name "*.log" -exec cat {} + | parallel --pipe awk '/ERROR/{count++} END{print count}' | awk '{sum+=$1} END{print sum}'
-
命令解释:
-
find . -name "*.log":-
从当前目录(
.)递归查找所有以.log结尾的文件。
-
-
parallel --pipe:-
--pipe选项将输入(即find找到的文件内容)分块传递给后续命令(这里是awk)。 -
GNU Parallel会将输入分成多个块,并在多个 CPU 核心上并行处理这些块。
-
-
awk '/ERROR/{count++} END{print count}':-
awk脚本的作用是:-
对每一行匹配
/ERROR/,如果匹配成功,则计数器count加 1。 -
在处理完所有行后,输出
count的值。
-
-
附录:AWK版本特性对比
| 特性 | AWK | Nawk | Gawk | Mawk |
|---|---|---|---|---|
| 正则表达式引擎 | BRE | ERE | ERE | DFA |
| 多维数组支持 | × | × | √ | × |
| TCP/IP网络编程 | × | × | √ | × |
| 性能(百万行/秒) | 2.1 | 3.4 | 1.8 | 4.7 |
| Unicode支持 | × | × | √ | × |
掌握AWK需要理解其设计哲学,通过大量实践积累模式。建议从简单文本处理入手,逐步过渡到复杂的数据分析场景。现代Gawk版本已支持网络编程和数据库访问,可以构建完整的CLI数据处理管道。
相关文章:
AWK系统学习指南:从文本处理到数据分析的终极武器 介绍
目录 一、AWK核心设计哲学解析 1.1 记录与字段的原子模型 1.2 模式-动作范式 二、AWK编程语言深度解析 2.1 控制结构 说明: 2.2 关联数组 代码说明: 示例输入和输出: 注意事项: 2.3 内置函数库 三、高级应用技巧 3.1…...
250207-MacOS修改Ollama模型下载及运行的路径
在 macOS 上,Ollama 默认将模型存储在 ~/.ollama/models 目录。如果您希望更改模型的存储路径,可以通过设置环境变量 OLLAMA_MODELS 来实现。具体步骤如下: 选择新的模型存储目录:首先,确定您希望存储模型的目标目录路…...
1、http介绍
一、HTTP 和 HTTPS 简介 HTTP(HyperText Transfer Protocol) 用途:用于网页数据传输(不加密)。协议特性:以明文形式传输数据,默认端口 80,无身份验证和完整性保护。典型场景…...
半导体行业跨网文件交换系统
在当今这个数字化转型的时代,半导体行业作为技术密集型产业,正面临着前所未有的信息安全挑战。随着企业内外网隔离措施的加强,如何实现既安全又高效的跨网文件交换,成为了众多半导体企业的一大难题。 特别是在研发和生产过程中产生…...
使用GD32F470的硬件SPI读写W25Q64
代码简单改下引脚定义便可以使用! 使用的单片机具体型号:GD32F470ZGT6 简单介绍下W25Q64: /* W25Q64 性能参数 */ /* 容量:8MByte 64Mbit */ /* 有128个块,每个块有64KByte */ /* 每个块有16个扇区,每个…...
02为什么 OD门和 OC门输出必须加上拉电阻?
为什么 OD(开漏)门和 OC(开集)门输出必须加上拉电阻? 1、首先一点,知道OD是说的MOS管,OC是说的三极管,二者的区别与联系大家应该都懂。 2、以OC门举例,芯片的OC门内部结…...
保姆级教程--DeepSeek部署
以DeepSeek-R1或其他类似模型为例,涵盖环境配置、代码部署和运行测试的全流程: 准备工作 1. 注册 Cloud Studio - 访问 [Cloud Studio 官网](https://cloudstudio.net/),使用腾讯云账号登录。 - 完成实名认证(如需长期使用…...
AI方案调研与实践 (不定期补充)
目录 说明 1. AI云主机准备 1.1 Ollama配置 设置模型保存路径 配置模型驻留内存时间 查看GPU状况命令: nvidia-smi 2. Deepseek 2.1 安装与使用 3. LobeChat配置 参考 说明 调研并实例化各种AI方案,探索训练/使用方式的最佳实践。 1. AI云主机准备 可以去一…...
人工智能大模型之模型蒸馏与知识蒸馏
一、背景介绍 随着人工智能技术的不断发展,大模型在各个领域的应用也越来越广泛。模型蒸馏(Model Distillation)和知识蒸馏(Knowledge Distillation)是两种非常重要的模型压缩技术,它们可以帮助我们将大型…...
[手机Linux] onepluse6T 系统重新分区
一,刷入TWRP 1. 电脑下载 Fastboot 工具(解压备用)和对应机型 TWRP(.img 后缀文件,将其放入前面解压的文件夹里) 或者直接这里下载:TWRP 2. 将手机关机,长按音量上和下键 开机键 进入 fastbo…...
k8s部署elasticsearch
前置环境:已部署k8s集群,ip地址为 192.168.10.1~192.168.10.5,总共5台机器。 1. 创建provisioner制备器(如果已存在,则不需要) 制备器的具体部署方式,参考我之前的文章:k8s部署rab…...
知识图谱智能应用系统:数据分析与挖掘技术文档
一、概述 在知识图谱智能应用系统中,数据分析与挖掘模块是实现知识发现和智能应用的核心环节。该模块负责处理和分析来自数据采集与预处理模块的结构化和半结构化数据,提取有价值的知识,并将其转化为可用于知识图谱构建和应用的三元组数据。本技术文档详细介绍了数据分析与…...
YAML中的`---`:文档分隔符
前言 YAML(YAML Ain’t Markup Language)是一种简洁且易于人类阅读的数据序列化标准,广泛用于配置文件、数据存储以及应用程序之间的数据交换。然而,对于许多初学者来说,YAML的一些特性可能不太直观,比如-…...
本地部署DeepSeek
下载Docker Docker Desktop: The #1 Containerization Tool for Developers | Docker 下载安装ollama Download Ollama on macOS 下载完成后解压运行 终端输入 Ollama --version 输出对应版本号即为下载成功 如果没有弹出上述图片,浏览器输入http://localhos…...
21.[前端开发]Day21-HTML5新增内容-CSS函数-BFC-媒体查询
王者荣耀-网页缩小的问题处理 为什么会产生这个问题?怎么去解决 可以给body设置最小宽度 1 HTML5新增元素 HTML5语义化元素 HTML5其他新增元素 2 Video、Audio元素 HTML5新增元素 - video video支持的视频格式 video的兼容性写法 HTML5新增元素 - audio audio…...
nbmade-boot调用deepseek的api过程与显示
希望大家一起能参与我的新开源项目nbmade-boot: 宁波智能制造低代码实训平台 下面简单介绍调用最近大红的AI :deepseek的api过程与显示,包括前后端代码与效果图 一、后端代码 1、几个基础的java类 DeepSeekRequest .java package com.nbcio.demo.do…...
Linux:安装 node 及 nvm node 版本管理工具(ubuntu )
目录 方法一:手动下载安装文件安装方法二:curl安装 方法一:手动下载安装文件安装 git clone 远程镜像 git clone https://gitee.com/mirrors/nvm安装 nvm bash install.sh刷新配置,使配置在终端生效 // 方法 1 source /root/.…...
微服务日志查询难解决方案-EFK
前言 在微服务项目中,日志查询难是一个常见问题,主要原因包括:日志分散:微服务实例分布在多个节点或容器中,日志存储位置分散。格式不统一:不同服务可能使用不同的日志格式,难以统一查询。调用…...
【多线程-第三天-NSOperation和GCD的区别 Objective-C语言】
一、我们来看NSOperation和GCD的区别 1.我们来对比一下,NSOperation和GCD, 那这个代码,我们都写过了, 我们来看一下它们的特点啊,首先来看GCD, 1)GCD是C语言的框架,是iOS4.0之后推出的,并且它的特点是,针对多核做了优化,可以充分利用CPU的多核,OK,这是GCD, 2…...
【医院运营统计专题】2.运营统计:医院管理的“智慧大脑”
医院成本核算、绩效管理、运营统计、内部控制、管理会计专题索引 引言 在当今医疗行业快速发展的背景下,医院运营管理的科学性和有效性成为了决定医院竞争力和可持续发展能力的关键因素。运营统计作为医院管理的重要工具,通过对医院各类数据的收集、整理、分析和解读,为医…...
Ollama 部署 DeepSeek-R1 及Open-WebUI
Ollama 部署 DeepSeek-R1 及Open-WebUI 文章目录 Ollama 部署 DeepSeek-R1 及Open-WebUI〇、说明为什么使用本方案 一、 安装Ollama1、主要特点:2、安装3、验证 二、Ollama 部署 DeepSeek1、部署2、模型选用3、Ollama 常用命令4、Ollama模型默认存储路径 安装open-w…...
Docker 容器 Elasticsearch 启动失败完整排查记录
背景 在服务器上运行 Docker 容器 es3,但 Elasticsearch 无法正常启动,运行 docker ps -a 发现 es3 处于 Exited (1) 状态,即进程异常退出。 本次排查从错误日志、容器挂载、权限问题、SELinux 影响、内核参数等多个方面入手,最…...
离线安装Appium Server
1、问题概述? 安装Appium通常有两种方式: 第一种:下载exe安装包,这种是Appium Server GUI安装方式,缺点是通过命令启动不方便。 第二种:通过cmd安装appium server,可以通过命令方式启动,比较方便。 问题:在没有外网的情况下,无法通过命令在cmd中安装appium server…...
Vite 打包原理
🤍 前端开发工程师、技术日更博主、已过CET6 🍨 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 🕠 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 🍚 蓝桥云课签约作者、上架课程《Vue.js 和 E…...
目前推荐的优秀编程学习网站与资源平台,涵盖不同学习方式和受众需求
一、综合教程与互动学习平台 菜鸟教程 特点:适合零基础新手,提供免费编程语言教程(Python、Java、C/C++、前端等),页面简洁且包含大量代码示例,支持快速上手。适用人群:编程入门者、需要快速查阅语法基础的学习者。W3Schools 特点:专注于Web开发技术(HTML、CSS、JavaS…...
【大模型】Ubuntu下安装ollama,DeepSseek-R1:32b的本地部署和运行
1 ollama 的安装与设置 ollama官网链接:https://ollama.com/ 在左上角的【Models】中展示了ollama支持的模型在正中间的【Download】中课可以下载支持平台中的安装包。 其安装和模型路径配置操作流程如下: ollama的安装 这里选择命令安装curl -fsSL …...
蓝桥杯---力扣题库第38题目解析
文章目录 1.题目重述2.外观数列举例说明3.思路分析(双指针模拟)4.代码说明 1.题目重述 外观数列实际上就是给你一串数字,我们需要对于这个数据进行一个简单的描述罢了; 2.外观数列举例说明 外观数列都是从1开始的,也…...
oCam:免费且强大的录屏软件
今天给大家推荐一个非常好的录屏软件。几乎可以满足你日常工作的需求。而且软件完全免费,没有任何的广告。 oCam:免费且强大的录屏软件 oCam是一款功能强大的免费录屏软件,支持屏幕录制、游戏录制和音频录制等多种模式,能够满足不…...
Day81:数据的保存
在编程中,数据保存是非常重要的,它使得程序能够持久化存储数据,并在程序重启后继续使用。这一节,我们将介绍如何使用 Python 来保存数据,涉及常见的几种方式,包括将数据保存到文件中、使用数据库等方法。 1. 保存数据到文本文件 文本文件是最常用的数据存储方式之一。你…...
苍穹外卖 项目记录 day11 Spring Task订单定时处理-来单提醒-客户催单
文章目录 Spring Taskcron表达式Spring Task使用步骤订单状态定时处理WebSocketWebSockt入门示例来单提醒客户催单 Spring Task Spring Task 是Spring框架提供的任务调度工具,可以按照约定的时间自动执行某个代码逻辑。 应用场景: 1). 信用卡每月还款…...
