当前位置:首页 > 技术 > 正文内容

Linux 实战:awk 文本处理全解析

访客 技术 2026年6月2日 1

awk 是一种强大的模式扫描与文本处理语言,广泛应用于 Linux/Unix 环境下对文本和数据进行结构化处理。它可以接收标准输入、一个或多个文件,甚至其他命令的输出作为数据源。除了在命令行中直接使用,awk 更常以脚本形式编写复杂逻辑。其内置支持数组、函数等特性,与 C 语言有诸多相似之处,而灵活性正是 awk 最突出的优势。

语法格式

awk [选项] '脚本' 变量=值 文件名

常用参数

  • -F:指定字段分隔符(可为字符串或正则表达式)
  • -f:从脚本文件读取 awk 命令
  • -v 变量=值:赋值变量,用于将外部变量传递给 awk

脚本基本结构

awk 'BEGIN{ print "开始" } 模式{ 命令 } END{ print "结束" }' 文件名

一个 awk 脚本通常由三部分组成:BEGIN 语句块、模式匹配语句块和 END 语句块,三者均为可选项。

工作原理:

  1. 首先执行 BEGIN 语句块(如果存在)
  2. 然后从文件或标准输入逐行读取,每行执行 pattern 语句块,直至文件全部读取完毕
  3. 最后执行 END 语句块(如果存在)

实例展示

# 仅有 BEGIN 和 END,无 pattern 部分
echo "hello" | awk 'BEGIN{ print "welcome" } END{ print "2025-03-15" }'
# 输出:
# welcome
# 2025-03-15

# 包含 pattern 部分,默认打印当前行
echo -e "hello" | awk 'BEGIN{ print "welcome" } {print} END{ print "2025-03-15" }'
# 输出:
# welcome
# hello
# 2025-03-15
# 注意:{print} 不指定参数时默认打印整行

# 使用 print 以逗号分隔输出,实际以空格分隔
echo | awk '{ a="hello"; b="world"; c="awk"; print a,b,c; }'
# 输出:hello world awk

# print 中双引号用于字符串拼接
echo | awk '{ a="user"; b="example"; c="com"; print a"@"b"."c; }'
# 输出:user@example.com

awk 变量

内置变量

  • $0:当前记录(整行)
  • $1 ~ $n:当前记录的第 N 个字段
  • FS:输入字段分隔符(与 -F 作用相同),默认空格
  • RS:输入记录分隔符,默认换行符
  • NF:当前行字段数量(列数)
  • NR:已读取的记录数(行号),从 1 开始
  • OFS:输出字段分隔符,默认空格
  • ORS:输出记录分隔符,默认换行符

外部变量传递

#!/bin/bash
x=200
y=300
echo | awk '{print v1*v2}' v1=$x v2=$y
# 输出:60000

运算与判断

算术运算符

  • + -:加、减
  • * / %:乘、除、求余
  • ^ **:求幂
  • ++ --:自增、自减(可作为前缀或后缀)
# 非数值在算术运算中自动转为0
awk 'BEGIN{a="x"; print a++, --a, a--, ++a}'
# 输出:0 0 0 1

赋值运算符

= += -= *= /= %= ^= **=

正则运算符

  • ~:匹配正则表达式
  • !~:不匹配正则表达式

逻辑运算符

  • ||:逻辑或
  • &&:逻辑与

关系运算符

< <= > >= != ==

其他运算符

  • $:字段引用
  • 空格:字符串连接符
  • ?::三目运算符
  • in:检查数组中是否存在某键值

正则表达式

^      行首定位
$      行尾定位
.      匹配任意单个字符
*      匹配0个或多个前导字符
+      匹配1个或多个前导字符
?      匹配0个或1个前导字符
[]     匹配指定字符组内的任一字符(如 [^ab])
[^]    匹配不在指定字符组内的任一字符
()     子表达式分组
|      逻辑或(二选一)
\      转义符
~,!~   匹配/不匹配条件
x{m}    x重复m次
x{m,}   x至少重复m次
x{m,n}  x重复m到n次(需加 --posix 或 --re-interval 参数)

实用示例

# 以冒号分隔,打印第2列
awk -F: '{print $2}' datafile

# 以冒号分隔,打印以"Dan"开头的行的第2列
awk -F: '/^Dan/{print $2}' datafile

# 打印以C或E开头的行的第1列
awk -F: '/^[CE]/{print $1}' datafile

# 打印第1列长度为4的行(以冒号分隔)
awk -F: 'length($1)==4 {print $1}' datafile

# 匹配包含"916"的行,打印第1列
awk -F: '/916/{print $1}' datafile

# 在以Dan开头的行的第5列前添加字母"a"
awk -F: '/^Dan/{print "a"$5}' 2.txt

# 以逗号分隔打印第2列和第1列(顺序调换)
awk -F: '{print $2","$1}' datafile

# 第5列等于68900的行,打印第1列
awk -F: '$5==68900 {print $1}' 2.txt

# 第1列为"Tommy Savage"的行,打印第5列
awk -F: '$1=="Tommy Savage" {print $5}' 2.txt

# 统计当前目录下所有文件字节数总和
ls -l | awk 'BEGIN{sum=0} {sum+=$5} END{print "总字节数:", sum}'

# 以MB为单位显示总大小
ls -l | awk 'BEGIN{sum=0} {sum+=$5} END{printf "总大小: %.2f MB\n", sum/1024/1024}'

# 算术赋值测试
awk 'BEGIN{a=20; a+=10; print a}'
# 输出:30

# 正则匹配字段内容
echo | awk 'BEGIN{str="hello123world"} str~/[0-9]+/{print "包含数字"}'

# 三目运算符示例
awk 'BEGIN{a=5; print a>3?"大":"小"}'
# 输出:大

# 匹配包含"root"的整行(使用默认空格分隔)
awk '/root/{print $0}' /etc/passwd

# 指定冒号分隔,匹配第5个字段包含"root"的行
awk -F: '$5~/root/{print $0}' /etc/passwd

# 提取网卡IP地址(适配不同Linux发行版)
ip addr show eth0 | awk 'BEGIN{FS="[[:space:]:]+"} NR==2{print $4}'

# 将文件内容全部转为大写输出
awk '{print toupper($0)}' test.txt
标签: awk

相关文章

Linux crontab 详解

1) crontab 是什么cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。常见两类:用户 crontab:每个用户一份(crontab -e 编辑)系统级 crontab / cron.d:可指定执行用户(/etc/crontab、/etc/cron.d/*)2) crontab 时间...

富文本里可以允许的 HTML 属性

一、所有标签默认允许的安全属性(极少)class        (可选)id           (通常建议禁用)title️ 注意:id 容易被滥用做锚点注入,很多系统直接禁用class 允许的话最好只允许固定前缀(如 editor-*)二、a 标签允许属性<a href="" t...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。