awk命令

awk 是一种强大的文本处理工具,主要用于在 Unix-like 系统(包括 Linux 和 macOS)中处理和分析结构化数据。它是基于模式匹配和动作的脚本语言,由 Alfred Aho、Peter Weinberger 和 Brian Kernighan 在 1977 年开发(故名"awk"取自三人姓氏首字母)。awk 常用于处理日志文件、CSV 数据、报表生成等场景。它支持正则表达式、变量、函数和数组,类似于一个小型编程语言。

awk 的核心思想是:读取输入文件(或标准输入),逐行处理,每行被拆分成字段(默认以空格分隔),然后根据模式执行动作。

1. 基本语法

awk 的基本命令格式:

复制代码
awk [选项] '模式 {动作}' 文件名
  • 模式:可选,用于匹配行(如正则表达式、条件判断)。如果省略,则对所有行执行动作。
  • 动作:用大括号 {} 包围的语句,如 print、printf 等。如果省略,则默认打印匹配行。
  • 文件名:输入文件,可以是多个文件或标准输入(用 - 表示)。如果省略,默认从标准输入读取。

示例:

复制代码
awk '{print $1}' file.txt  # 打印 file.txt 中每行的第一个字段

awk 脚本也可以写成独立文件:

复制代码
awk -f script.awk file.txt

其中 script.awk 包含模式和动作。

2. 常用选项

awk 支持多种选项,以下是常见选项的表格:

选项 描述 示例
-F fs 指定字段分隔符(默认空格或制表符)。fs 可以是正则表达式。 awk -F ":" '{print $1}' /etc/passwd (用冒号分隔,打印用户名)
-f file 从文件中读取 awk 脚本。 awk -f myscript.awk data.txt
-v var=value 定义变量并赋值,可在 BEGIN 块中使用。 awk -v name="Alice" 'BEGIN {print name}'
-W option 特定实现选项(如 gawk 的 -W traditional 用于兼容模式)。 awk -W version (显示版本)
-- 结束选项处理,后续参数视为文件名。 用于处理以 - 开头的文件名。

注意:awk 有多种实现,如 nawk(New awk)、gawk(GNU awk,是 Linux 默认的)。gawk 扩展了标准 awk,支持更多功能。

3. 内置变量

awk 提供了许多内置变量,用于访问行、字段和环境信息。以下是常用内置变量的表格:

变量 描述 示例
$0 当前整行内容。 print $0 打印整行。
$n 第 n 个字段($1 是第一个)。 print 1, 3 打印第一和第三个字段。
NF 当前行字段数。 if (NF > 3) print $0 只打印字段数 >3 的行。
NR 当前记录号(行号,从 1 开始)。 print NR, $0 带行号打印。
FNR 当前文件记录号(多文件时独立计数)。 与 NR 类似,但每个文件重置。
FS 字段分隔符(默认空格)。 FS = "," 设置为逗号(CSV)。
OFS 输出字段分隔符(默认空格)。 OFS = "\t" 输出用制表符分隔。
RS 记录分隔符(默认换行符)。 RS = "" 以空行分隔段落。
ORS 输出记录分隔符(默认换行符)。 ORS = "\n\n" 输出加空行。
FILENAME 当前文件名。 print FILENAME 显示处理的文件。
ARGC / ARGV 参数数量和数组。 用于访问命令行参数。
4. 特殊块

awk 支持特殊模式块,这些块不依赖输入行:

  • BEGIN {动作}:在处理任何输入前执行一次,常用于初始化变量、打印表头。

  • END {动作}:在处理所有输入后执行一次,常用于汇总、打印总计。

  • 示例:

    复制代码
    awk 'BEGIN {print "Start"} {print $1} END {print "End"}' file.txt
5. 模式和条件
  • 正则匹配:/pattern/ 或 n \~ /pattern/。 示例:awk '/error/ {print 0}' log.txt 打印含 "error" 的行。
  • 关系运算:==、!=、> 等。 示例:awk '2 \> 100 {print 1}' data.txt 第二字段 >100 的行打印第一字段。
  • 逻辑运算:&&、||、!。
  • 范围模式:pattern1, pattern2 从 pattern1 到 pattern2 的行。 示例:awk '/start/, /end/' file.txt。
6. 动作和函数
  • print:简单输出。print 1, 2(逗号自动加 OFS)。

  • printf:格式化输出,如 C 风格。printf "%-10s %d\n", 1, 2(左对齐字符串,整数)。

  • 内置函数

    • 字符串:length(str)、substr(str, start, len)、index(str, sub)、tolower(str)、gsub(regex, repl, str)。
    • 数学:int(x)、sqrt(x)、rand()、sin(x) 等。
    • 时间:systime()、strftime(format, timestamp)(gawk)。
  • 控制结构:if-else、for、while、do-while、break、continue。

  • 数组 :关联数组(哈希)。arr[key] = value;遍历 for (key in arr)。 示例:统计单词出现次数。

    复制代码
    awk '{for(i=1;i<=NF;i++) count[$i]++} END {for(word in count) print word, count[word]}' file.txt
7. 示例应用
  1. 提取列:awk '{print $2}' file.txt > column2.txt。

  2. 求和:awk '{sum += $1} END {print sum}' numbers.txt。

  3. 过滤:awk -F "," '3 == "active" {print 1}' users.csv。

  4. 替换:awk '{gsub(/old/, "new", $0); print}' file.txt。

  5. 多文件处理:awk 'FNR==1 {print FILENAME} {print $0}' file1.txt file2.txt。

  6. 复杂脚本 :计算平均值。

    复制代码
    awk 'BEGIN {sum=0; count=0} {sum += $1; count++} END {if(count>0) print sum/count}' data.txt
8. 高级特性(gawk 扩展)
  • 多维数组:arr[x,y] = value(实际是 arr["x\034y"])。
  • 网络编程:/inet/tcp 等(用于 socket)。
  • 扩展函数:用户定义函数 function name(args) {body}。
  • include:@include "file.awk" 包含其他脚本。
9. 注意事项
  • awk 默认忽略前导/尾随空格。
  • 处理大文件高效,但脚本复杂时考虑 Perl 或 Python。
  • 调试:用 print 插入检查点,或 gawk 的 --dump-variables。
  • 兼容性:标准 awk (POSIX) vs gawk(检查 awk --version)。
相关推荐
WW、forever2 小时前
【服务器】上传百度网盘数据至服务器
运维·服务器
清水白石0082 小时前
Python 柯里化完全指南:从函数式思想到工程实践
linux·服务器·python
m0_694845572 小时前
netcut 是什么?简单安全的在线剪贴板搭建与使用教程
运维·服务器·安全·开源·云计算·github
女王大人万岁2 小时前
Golang标准库 CGO 介绍与使用指南
服务器·开发语言·后端·golang
宸迪3 小时前
【python】使用uv管理项目包依赖
linux·python·uv
网云工程师手记3 小时前
DDNS-Go部署与使用体验:动态公网IP远程访问不再断
运维·服务器·网络·网络协议·网络安全
HalvmånEver3 小时前
Linux:基于信号量的环形队列与生产者消费者模型(一)
linux·运维·服务器·信号量
海兰4 小时前
手把手elasticsearch学习增删改查之“增”
运维·jenkins
威桑5 小时前
解决 Qt6 程序 在Linux 环境下无法输入中文的问题
linux·c++·qt