shell编程——AWK 从入门到精通

news2025/3/12 8:59:06

1. 前言

在日常运维、数据分析和开发工作中,处理文本数据是不可避免的任务。无论是从日志中提取关键信息,还是批量处理数据表,效率和灵活性都至关重要。AWK 是 UNIX/Linux 环境中一款轻量级却功能强大的文本处理工具,它以简洁的语法、强大的模式匹配功能和灵活的操作能力闻名,广泛用于日志分析、数据处理、自动化脚本等领域。

本篇文章将带你从零开始掌握 AWK,涵盖基础用法、进阶操作、高级技巧及常见应用场景,帮助你成为一名文本处理专家。


2. AWK 基本概念

什么是 AWK?

AWK 是一种专门用于处理文本的脚本语言,得名于三位开发者 Alfred Aho、Peter Weinberger 和 Brian Kernighan 的姓氏首字母。它设计的初衷是简化对结构化文本的处理任务。

  • 核心理念:逐行读取文件,按指定的模式匹配进行操作,最终输出处理结果。
  • 优势
    • 简洁的语法适合快速开发;
    • 支持复杂的逻辑和计算;
    • 与其他命令工具(如 grepsedsort)无缝结合。

基本语法结构

AWK 程序的基本结构如下:

awk '模式 {动作}' 文件
  • 模式:用于匹配输入的行。例如匹配特定字符串或满足某些条件的行。
  • 动作:对匹配到的行执行指定的操作,如打印、计算或替换。

示例:

ps | awk '{print $1}'
  • 上述命令中,{print $1} 是动作,表示输出每行的第一个字段。

字段分隔符

AWK 默认将空格或制表符作为字段分隔符,但可以通过 -F 选项自定义分隔符。例如:

awk -F ":" '{print $1}' /etc/passwd
  • 这里的 -F ":": 设置为字段分隔符,输出 /etc/passwd 文件中每行的第一个字段(即用户名)。

内置工作流

AWK 程序有三个主要的处理阶段:

  1. BEGIN:在读取任何输入文件之前执行,用于初始化。
  2. 主程序块:逐行处理输入文件中的内容。
  3. END:在处理完所有行后执行,用于汇总计算或输出最终结果。

例如:

awk 'BEGIN {print "开始处理..."} {print $1} END {print "处理结束"}' 文件

3. 基础用法

3.1 提取文本信息

提取文本中的某些字段或行是 AWK 最常见的操作之一:

  • 获取系统中所有运行的进程 ID:
    ps | awk '{print $1}'
    
  • /etc/passwd 中提取用户名:
    awk -F ":" '{print $1}' /etc/passwd
    

3.2 条件筛选

  • 提取行长度大于 7 的文本:
    awk 'length($0) > 7' /etc/shells
    
  • 筛选 /etc/shells 中内容等于 /bin/bash 的行:
    awk '{if ($0=="/bin/bash") print $0}' /etc/shells
    

3.3 脚本特性

AWK 支持控制流和简单计算,例如输出 1 到 10 的平方:

awk 'BEGIN{for(i=1;i<=10;i++) print "数字",i,"的平方为",i*i}'

4. 进阶使用

4.1 管道操作

AWK 通常与其他命令结合,处理复杂任务。例如:

  • 启动 Docker 中的所有容器:
    docker ps -a | awk '{print $1}' | tail -n +2 | xargs docker start
    
  • 停止 Docker 中的所有容器:
    docker ps -a | awk '{print $1}' | tail -n +2 | xargs docker stop
    

4.2 字符匹配

  • 筛选字段末尾不包含 test 的 Docker 容器:
    docker ps | awk '!match($NF,/^test/) {print NR,$NF}'
    
  • 上述命令通过正则表达式匹配字段,并排除特定条件。

4.3 字段统计

打印 /etc/shells 的最后一个字段并排序去重:

awk -F "/" '/^\// {print $NF}' /etc/shells | sort -u
  • /^\// 是一个正则表达式,用于匹配以斜杠 / 开头的行

5. 高级技巧

5.1 嵌套条件

通过复杂逻辑筛选数据,例如从日志中筛选错误条目:

awk '{if ($3=="ERROR" && $5>10) print $0}' server.log

5.2 自定义函数

AWK 支持定义函数,以实现复杂计算:

awk 'function fib(n) {if (n<=2) return 1; else return fib(n-1)+fib(n-2)} BEGIN {for(i=1;i<=10;i++) print fib(i)}'

5.3 多文件处理

合并两个文件并根据字段匹配:

awk 'NR==FNR{a[$1]=$2; next} $1 in a {print $1, $2, a[$1]}' file1 file2
  • file1file2 的第一个字段匹配,输出关联字段。

6. 性能优化

  • 减少重复计算
    awk '{sum+=$2} END {print "总和:", sum}' data.txt
    
  • 逐行处理大文件
    使用 getline 避免一次性加载大文件,节省内存:
    awk '{while (getline < "file.txt") print $0}'
    

7. 常用内建变量

变量描述
$0当前整行内容
$1,$2...当前行的第 N 个字段
NF当前行的字段数
NR当前行号(全局累计)
FNR当前行号(当前文件)
FS输入字段分隔符
OFS输出字段分隔符

8. 常见应用场景

  1. 日志分析:提取错误日志、统计关键字出现次数。
  2. 数据处理:筛选表格字段、生成统计报告。
  3. 自动化脚本:快速处理系统配置文件。

9. 总结

AWK 是 UNIX/Linux 环境中的利器,适用于各种文本处理需求。通过不断实践和优化,您将发现 AWK 的强大之处,从而极大提升工作效率。

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

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

相关文章

AI一键分析小红书对标账号‼️

宝子们&#xff0c;AI小助手近期发现了一款宝藏AI工具&#xff0c;拥有对标账号AI分析功能&#xff0c;只需10秒就能全面掌握对标账号的运营情况&#xff0c;并且可以根据分析结果提供创作方向和灵感&#xff0c;轻松助力1:1复刻起号&#xff01; 功能亮点&#xff1a; &…

大腾智能CAD:国产云原生三维设计新选择

在快速发展的工业设计领域&#xff0c;CAD软件已成为不可或缺的核心工具。它通过强大的建模、分析、优化等功能&#xff0c;不仅显著提升了设计效率与精度&#xff0c;还促进了设计思维的创新与拓展&#xff0c;为产品从概念构想到实体制造的全过程提供了强有力的技术支持。然而…

VMware虚拟机 Ubuntu没有共享文件夹的问题

在虚拟机的Ubuntu系统中&#xff0c;共享文件目录存放在 mnt/hgfs 下面&#xff0c;但是我安装完系统并添加共享文件后发现&#xff0c;在mnt下连/hgfs目录都没有。 注意&#xff1a;使用共享文件目录需要已安装VMtools工具。 添加共享文件目录 一&#xff1a;在超级用户下 可…

OpenGL ES 01 渲染一个四边形

项目架构 着色器封装 vertex #version 300 es // 接收顶点数据 layout (location 0) in vec3 aPos; // 位置变量的属性位置值为0 layout (location 1) in vec4 aColors; // 位置变量的属性位置值为1 out vec4 vertexColor; // 为片段着色器指定一个颜色输出void main() {gl…

leetcode二叉搜索树部分笔记

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 二叉搜索树 1. 二叉搜索树的最小绝对差2. 二叉搜索树中第 K 小的元素3. 验证二叉搜索树 1. 二叉搜索树的最小绝对差 给你一个二叉搜索树的根节点 root &#xff0c;返回 树中…

推送本地仓库到远程git仓库

目录 推送本地仓库到远程git仓库1.1修改本地仓库用户名1.2 push 命令1.3远程分支查看 推送本地仓库到远程git仓库 删除之前的仓库中的所有内容&#xff0c;从新建库&#xff0c;同时创建一个 A.txt 文件 清空原有的远程仓库内容&#xff0c;重新创建一个新的仓库&#xff0c;…

暂停一下,给Next.js项目配置一下ESLint(Next+tailwind项目)

前提 之前开自己的GitHub项目&#xff0c;想着不是团队项目&#xff0c;偷懒没有配置eslint&#xff0c;后面发现还是不行。eslint的存在可以帮助我们规范代码格式&#xff0c;同时 ctrl s保存立即调整代码格式是真的很爽。 除此之外&#xff0c;团队使用eslint也是好处颇多…

基于微信小程序的小区疫情防控ssm+论文源码调试讲解

第2章 程序开发技术 2.1 Mysql数据库 为了更容易理解Mysql数据库&#xff0c;接下来就对其具备的主要特征进行描述。 &#xff08;1&#xff09;首选Mysql数据库也是为了节省开发资金&#xff0c;因为网络上对Mysql的源码都已进行了公开展示&#xff0c;开发者根据程序开发需…

Win11安装安卓子系统WSA

文章目录 简介一、启用Hyper-V二、安装WSA三、安装APKAPK商店参考文献 简介 WSA&#xff1a;Windows Subsystem For Android 一、启用Hyper-V 控制面板 → 程序和功能 → 启用或关闭 Windows 功能 → 勾选 Hyper-V 二、安装WSA 进入 Microsoft Store&#xff0c;下拉框改为 …

[面试题]--索引用了什么数据结构?有什么特点?

答&#xff1a;使用了B树&#xff1a; 时间复杂度&#xff1a;O(logN),可以有效控制树高 B树特点&#xff1a; 1.叶子节点之间有相互链接的作用&#xff0c;会指向下一个相近的兄弟节点。 MySQL在组织叶子节点使用的是双向链表 2.非叶子节点的值都保存在叶子节点当中 MySQL非叶…

Element plus 下拉框组件选中一个选项后显示的是 value 而不是 label

最近刚进行 Vue3 Element plus 项目实践&#xff0c;在进行表单二次封装的时候&#xff0c;表单元素 select 下拉框组件选中一个选项后显示的是 value 而不是 label&#xff0c;下面上代码&#xff1a; 原来的写法&#xff1a; <el-selectv-if"v.type select"…

bean创建源码

去字节面试&#xff0c;直接让人出门左拐&#xff1a;Bean 生命周期都不知道&#xff01; spring启动创建bean流程 下面就接上了 bean生命周期 doGetBean Object sharedInstance this.getSingleton(beanName); sharedInstance this.getSingleton(beanName, new ObjectF…

【C++】- 掌握STL List类:带你探索双向链表的魅力

文章目录 前言&#xff1a;一.list的介绍及使用1. list的介绍2. list的使用2.1 list的构造2.2 list iterator的使用2.3 list capacity2.4 list element access2.5 list modifiers2.6 list的迭代器失效 二.list的模拟实现1. list的节点2. list的成员变量3.list迭代器相关问题3.1…

泷羽sec学习打卡-brupsuite8伪造IP和爬虫审计

声明 学习视频来自B站UP主 泷羽sec,如涉及侵权马上删除文章 笔记的只是方便各位师傅学习知识,以下网站只涉及学习内容,其他的都 与本人无关,切莫逾越法律红线,否则后果自负 关于brupsuite的那些事儿-Brup-FaskIP 伪造IP配置环境brupsuite导入配置1、扩展中先配置python环境2、安…

挑战一个月基本掌握C++(第五天)了解运算符,循环,判断

一 运算符 运算符是一种告诉编译器执行特定的数学或逻辑操作的符号。C 内置了丰富的运算符&#xff0c;并提供了以下类型的运算符&#xff1a; 算术运算符关系运算符逻辑运算符位运算符赋值运算符杂项运算符 1.1 算术运算符 假设变量 A 的值为 10&#xff0c;变量 B 的值为…

JAVA没有搞头了吗?

前言 今年的Java程序员群体似乎承受着前所未有的焦虑。投递简历无人问津&#xff0c;难得的面试机会也难以把握&#xff0c;即便成功入职&#xff0c;也往往难以长久。于是&#xff0c;不少程序员感叹&#xff1a;互联网的寒冬似乎又一次卷土重来&#xff0c;环境如此恶劣&…

Linux -- 线程控制相关的函数

目录 pthread_create -- 创建线程 参数 返回值 代码 -- 不传 args&#xff1a; 编译时带 -lpthread 运行结果 为什么输出混杂&#xff1f; 如何证明两个线程属于同一个进程&#xff1f; 如何证明是两个执行流&#xff1f; 什么是LWP&#xff1f; 代码 -- 传 args&a…

达梦查询表字段详细信息脚本(字段名称、描述、类型、长度及是否为空)

达梦查询表字段详细信息脚本&#xff08;字段名称、描述、类型、长度及是否为空&#xff09; 该SQL 脚本&#xff0c;用于查询表中字段的基本信息&#xff0c;包括字段名称、描述、数据类型、数据长度、是否为空及是否为主键等属性。 SQL 脚本 -- 输入变量 DECLAREp_owner VA…

学习笔记073——Java中的【Object】和【包装类】

文章目录 1、Object 类1.1、什么是 Object 类1.2、可能被重写的常用方法 2、包装类2.1、什么是包装类&#xff1f;2.2、装箱和拆箱 1、Object 类 1.1、什么是 Object 类 Java 通过类来构建代码的结构&#xff0c;类分为两种&#xff1a; 1、Java 提供的工具类&#xff0c;不…