awk高级用法——内置变量、函数与进阶技巧

简介: 本文深入讲解awk进阶核心:内置变量(NR/FNR/NF/FS/OFS/FILENAME/ARGC/ARGV等)与内置函数(length/substr/index/gsub等),涵盖行字段统计、多文件处理、动态分隔符、字符串操作等高频场景,配丰富实操示例,助你从入门迈向精通。

1. 前言:进阶的意义

通过前两篇的学习,你已经掌握了awk的基础运行方式和核心命令行参数,能够处理大部分简单的文本处理需求(比如筛选行、提取字段、格式化输出)。但实际工作中,我们遇到的文本处理场景往往更复杂——比如统计行数、计算字段总和、按条件循环处理、加载外部脚本库,这时候就需要用到awk的高级功能。

本篇重点讲解:awk内置变量、内置函数、流程控制、环境变量、文件包含与动态扩展,每个知识点都配详尽示例,确保你学完就能应对复杂场景,真正做到“精通awk”。

提示:所有示例依然基于前两篇的test.txt和test.csv文件,若你没有,可参考前两篇的命令重新创建。

2. 核心进阶:awk内置变量(必掌握)

awk有很多内置变量(系统自带,无需手动定义),这些变量能帮我们快速获取文本的关键信息(比如行号、字段数、文件名),极大提升处理效率。重点讲解10个最常用的内置变量,按用途分类,方便记忆。

2.1 行与字段相关变量(最常用)

内置变量 说明 实操示例
NR Number of Records,当前处理的行号(所有文件累计) awk '{print "行号:"NR, "内容:"$0}' test.txt(打印每行行号和内容)
FNR File Number of Records,当前文件的行号(多文件处理时,每个文件重新计数) awk '{print "当前文件行号:"FNR, "内容:"$0}' test.txt test.csv(处理两个文件,分别计数)
NF Number of Fields,当前行的字段数($1到$NF就是当前行的所有字段) awk -F "," '{print "当前行字段数:"NF, "最后一列:"$NF}' test.csv(打印每行列数和最后一列)
FS Field Separator,字段分隔符(和-F参数功能一致,可在脚本中动态修改) awk 'BEGIN {FS=","} {print $1, $2}' test.csv(在BEGIN中设置分隔符,等价于-F ",")
OFS Output Field Separator,输出字段分隔符(默认是空格,可修改) awk -F "," 'BEGIN {OFS="|"} {print $1, $2}' test.csv(输出时用|分隔字段)

实操示例(重点练习,可直接复制):

# 示例1:用NR和NF筛选行(筛选字段数大于3的行,且行号大于1)
awk -F "," 'NR>1 && NF>3 {print "行号"NR, "字段数"NF, "内容:"$0}' test.csv
# 输出(test.csv中,数据行字段数都是4,表头字段数4,跳过表头):
# 行号2 字段数4 内容:张三,20,男,北京
# 行号3 字段数4 内容:李四,25,女,上海
# 行号4 字段数4 内容:王五,30,男,广州

# 示例2:用FNR处理多个文件(分别显示两个文件的行号)
awk '{print "文件:"FILENAME, "行号:"FNR, "内容:"$0}' test.txt test.csv
# 输出(test.txt行号1-3,test.csv行号1-4):
# 文件:test.txt 行号:1 内容:张三 20 男
# ...(省略中间内容)
# 文件:test.csv 行号:1 内容:姓名,年龄,性别,城市
# ...(省略中间内容)

# 示例3:修改OFS,格式化输出(用逗号分隔输出字段)
awk -F "," 'BEGIN {OFS=","} NR>1 {print $1, $2, $4}' test.csv
# 输出(和CSV格式一致):
# 张三,20,北京
# 李四,25,上海
# 王五,30,广州

# 示例4:动态修改FS(先按空格分隔,再按逗号分隔)
echo -e "张三 20,男\n李四 25,女" | awk 'BEGIN {FS=" "} {print $1, $2; FS=","; print $1, $2}'
# 输出(第一行按空格分隔,第二行按逗号分隔):
# 张三 20,男
# 20 男

2.2 文件与参数相关变量

内置变量 说明 实操示例
FILENAME 当前处理的文件名(多文件处理时,显示当前正在处理的文件) awk '{print "正在处理:"FILENAME, "行号:"NR}' test.txt test.csv
ARGC Argument Count,命令行参数的个数(包括awk命令本身) awk '{print ARGC}' test.txt test.csv(输出3,因为参数是awk、test.txt、test.csv)
ARGV Argument Vector,命令行参数数组(ARGV[0]是awk,ARGV[1]是第一个文件,以此类推) awk 'BEGIN {for(i=0;i<ARGC;i++) print ARGV[i]}' test.txt test.csv
ARGIND 当前处理的参数在ARGV数组中的索引(对应ARGV的下标) awk '{print "当前参数索引:"ARGIND, "文件名:"FILENAME}' test.txt test.csv

实操示例(重点练习):

# 示例1:用ARGC和ARGV,动态指定处理的文件
# 脚本逻辑:如果参数个数大于2,就处理所有文件,否则提示“缺少文件”
awk 'BEGIN {
    if(ARGC<3) {
        print "错误:缺少处理文件!"
        exit 1  # 退出,状态码1(表示错误)
    } else {
        print "共处理"ARGC-1"个文件:"
        for(i=1;i<ARGC;i++) print ARGV[i]
    }
}' test.txt test.csv
# 输出:
# 共处理2个文件:
# test.txt
# test.csv

# 示例2:用ARGIND区分不同文件,分别处理
awk '{
    if(ARGIND==1) {print "处理test.txt:"$0}  # ARGIND=1对应第一个文件test.txt
    if(ARGIND==2) {print "处理test.csv:"$0}  # ARGIND=2对应第二个文件test.csv
}' test.txt test.csv

3. 核心进阶:awk内置函数(实用高频)

awk提供了很多内置函数,涵盖字符串处理、数值计算、时间处理等,重点讲解日常工作中最常用的8个,按用途分类,每个函数配详细示例,避免冗余。

3.1 字符串处理函数(最常用)

函数名 说明 语法 实操示例
length() 计算字符串长度(中文UTF-8按多字节计算,-b参数下按单字节) length(字符串) awk '{print $1, "长度:"length($1)}' test.txt(输出张三 长度:2)
substr() 截取字符串(从指定位置开始,截取指定长度) substr(字符串, 起始位置, 长度) awk '{print substr($1,1,1)}' test.txt(截取姓名第一个字:张、李、王)
index() 查找字符串在另一个字符串中的位置(找不到返回0) index(原字符串, 目标字符串) awk -F "," '{print index($4,"京")}' test.csv(查找“京”在城市中的位置)
gsub() 全局替换字符串(替换所有匹配的内容,区别于sub()只替换第一次) gsub(匹配规则, 替换后内容, 原字符串) awk '{gsub("男","男性"); print}' test.txt(将所有“男”替换为“男性”)

实操示例(重点练习):

# 示例1:用substr()截取日志中的IP(模拟日志)
echo -e "192.168.1.1 - [2024-01-01] \"GET /index.html\"" > access.log
# 截取IP(前11个字符)
awk '{print "访问IP:"substr($1,1,11)}' access.log
# 输出:访问IP:192.168.1.1

# 示例2:用gsub()替换CSV中的逗号为空格,并重命名字段
awk -F "," 'BEGIN {OFS=" "} {gsub(","," ",$0); print $1, $2, $3, $4}' test.csv
# 输出(逗号替换为空格):
# 姓名 年龄 性别 城市
# 张三 20 男 北京

# 示例3:结合index()筛选包含指定字符的行
# 筛选城市中包含“京”的用户
awk -F "," 'NR>1 && index($4,"京")>0 {print $1, $4}' test
相关文章
|
8月前
|
运维 Linux 应用服务中间件
Linux sort命令实战教程
本文详解Linux `sort`命令:从基础排序、数字/反向/去重/忽略大小写等常用参数,到按字段(-k)、分隔符(-t)、月份(-M)、人类可读大小(-h)等进阶用法,并附日志、CSV、文件大小等实战案例。通俗易懂,示例可直接运行,新手也能快速掌握。
|
8月前
|
数据采集 Java Go
爬虫项目该选 Python 还是 Golang?看这篇就够了
本文对比Python与Golang在爬虫开发中的七大维度:语法简洁性、第三方库丰富度(如Scrapy vs Colly)、并发性能(Goroutine vs GIL限制)、内存占用、代码可读性、数据处理能力(Pandas等优势)及部署便捷性(Go可直接编译为跨平台二进制),助你按需选型。
558 10
|
8月前
|
存储 安全 Linux
Linux sed命令详细教程
sed是Linux下高效流编辑器,GNU sed为其主流实现。它单次遍历输入,支持管道过滤、批量配置修改与日志处理,具备无交互、原地编辑、扩展正则等优势,是Shell自动化必备利器。
|
8月前
|
Linux Shell Perl
awk入门基础——什么是awk?怎么跑起来?
awk是Linux下强大的文本处理工具兼脚本语言,擅长逐行提取、过滤与计算(如日志IP提取、字段统计)。其核心为“读取—处理—输出”三步机制,支持命令行单引号脚本和外部脚本文件两种运行方式,基于gawk兼容性强,入门简单、实用高效。
|
机器学习/深度学习 人工智能 自然语言处理
还在想开题报告?SurveyGO卷姬:清华开源学术论文AI写作神器,一键生成文献综述
SurveyGO是清华与面壁智能联合开源的AI论文写作工具,采用LLMxMapReduce-V2技术实现文献智能聚合,能根据用户输入主题快速生成结构严谨、引用可靠的学术综述。
2033 1
还在想开题报告?SurveyGO卷姬:清华开源学术论文AI写作神器,一键生成文献综述
|
9月前
|
Linux 网络安全
一文读懂NAT:SNAT与DNAT的“庐山真面目”及firewalld实战配置
本文详解NAT核心技——SNAT与DNAT,通过生活类比解析地址转换原理。针对不同系统版本,分别介绍firewalld新旧版配置方法:旧版用Direct接口,新版推荐Policy策略模式,涵盖命令示例与验证方式,助你轻松实现内网共享上网与服务发布。
|
9月前
|
存储 Kubernetes 中间件
在Kubernetes集群中部署NFS Subdir ExternalProvisioner的完整复盘
本文完整复盘Kubernetes中NFS Subdir External Provisioner的Helm部署实践,涵盖环境准备、原理剖析、分步安装、动态PV创建与回收验证。通过配置StorageClass实现PVC自动绑定NFS子目录,支持ReadWriteMany,提升共享存储管理效率。(239字)
459 1
|
9月前
|
存储 安全 Cloud Native
Rocky Linux下配置nfs
NFS(网络文件系统)是类Unix系统间分布式文件共享的核心协议,支持跨机器数据共享,广泛应用于云原生、企业文件服务。本文详解NFS在Rocky Linux下的部署:从基础概念、组件安装(nfs-utils、rpcbind)、服务器配置(/etc/exports)、防火墙设置到客户端挂载与自动加载(fstab、autofs),并提供常见问题排查方案,助力构建高效安全的共享存储环境。
|
9月前
|
安全 关系型数据库 MySQL
Rocky Linux9 selinux介绍及常见问题排查
SELinux是Rocky Linux 9默认启用的安全模块,通过委任式存取控制(MAC)机制,基于程序域(Domain)与文件类型(Type)的策略规则,实现对系统资源的精细化访问控制。相比传统DAC,SELinux即使root也无法绕过权限限制,显著提升安全性。其核心组件包括主体、目标、政策和安全上下文,配合`setroubleshoot`、`auditd`等工具可高效排查“403 Forbidden”等常见问题。通过`restorecon`、`semanage`修复文件类型,或使用`setsebool -P`调整布尔值,可在不关闭SELinux的前提下解决服务权限需求