一、基本概念
awk 是 Linux/Unix 中功能强大的文本处理编程工具,其核心特点包括:
- 按行处理文本数据,支持字段(列)级操作。
- 内置变量、运算符、控制流(条件/循环)及函数。
- 适用于数据提取、统计、格式化输出等场景。
- 名称来自其三位创始人姓氏首字母(Aho, Weinberger, Kernighan)。
二、语法结构
awk [选项] '模式 {动作}' 文件1 文件2... # 直接编写脚本
awk [选项] -f 脚本文件 文件1 文件2... # 从文件读取脚本
基本执行流程:
- 逐行读取输入文件。
- 根据
模式匹配当前行,若匹配则执行动作。 - 默认输出处理后的行(除非动作中明确禁止)。
三、常用选项
| 选项 | 说明 |
|---|---|
-F fs | 指定输入字段分隔符(默认空格/TAB) |
-v var=value | 定义变量(可在脚本中使用) |
-f script.awk | 从文件读取awk脚本 |
-O | 启用优化处理(仅GNU awk支持) |
--csv | 以CSV模式解析输入(Gawk 4.0+) |
四、核心语法要素
1. 内置变量
| 变量 | 说明 |
|---|---|
$0 | 当前行的全部内容 |
$1, $2... | 第1、2个字段(列) |
NF | 当前行的字段总数(列数) |
NR | 当前处理的行号(累计所有文件) |
FNR | 当前文件的行号(各文件独立计数) |
FS | 输入字段分隔符(默认为空格/TAB) |
OFS | 输出字段分隔符(默认为空格) |
FILENAME | 当前处理的文件名 |
2. 模式(Pattern)
- 空模式:匹配所有行(如
{print $0})。 - 正则匹配:
/正则表达式/
示例:awk '/error/ {print NR,$0}' log.txt(输出含"error"的行及其行号)。 - 范围模式:
模式1, 模式2(匹配从模式1到模式2之间的行)。 - 条件表达式:如
NR > 10、$3 == "admin"。
3. 动作(Action)
- 用
{}包裹,包含一个或多个语句。 - 常用操作:
print,printf, 算术运算, 流程控制(if/else,for,while)等。
4. BEGIN与END块
- BEGIN:在处理输入前执行一次
示例:awk 'BEGIN {FS=":"; OFS="\t"} {print $1,$3}' /etc/passwd。 - END:在处理完所有输入后执行一次
示例:awk '{sum+=$1} END {print "总和=", sum}' data.txt。
五、典型应用示例
1. 基础字段处理
# 提取日志中的IP和访问次数(假设第1列为IP)
awk '{ip_count[$1]++} END {for(ip in ip_count) print ip, ip_count[ip]}' access.log
# 格式化输出:列对齐(printf)
awk '{printf "%-15s %10d\n", $1, $3}' sales.csv
-
打印文件的所有内容
awk '{ print }' file.txt这实际上等同于
cat file.txt,因为awk默认会对每一行执行print操作。 -
打印文件的第二列
假设文件
file.txt的字段由空格分隔:awk '{ print $2 }' file.txt -
使用逗号作为字段分隔符打印第二列
awk -F, '{ print $2 }' file.txt -
打印行号和行内容
awk '{ print NR, $0 }' file.txt -
计算每行的字段总和
假设文件
file.txt中的字段是数字,且由空格分隔:awk '{ sum = 0; for (i = 1; i <= NF; i++) sum += $i; print sum }' file.txt -
打印文件中的特定行
打印文件中的第三行:
awk 'NR == 3 { print }' file.txt -
基于模式匹配打印行
打印包含 "error" 的行:
awk '/error/ { print }' file.txt -
设置输出字段分隔符
使用逗号作为输出字段分隔符打印第二和第三列:
awk -F' ' 'BEGIN { OFS = "," } { print $2, $3 }' file.txt -
使用变量
在命令行中设置变量
x并打印第x列:x=3 awk -v col=$x '{ print $col }' file.txt -
从文件中读取
awk程序将
awk程序保存在script.awk文件中,并处理file.txt:awk -f script.awk file.txtscript.awk内容示例:{ print $2, $3 }
2. 条件筛选与计算
# 筛选第3列大于100的行,并计算平均值
awk '$3 > 100 {sum+=$3; count++} END {if(count>0) print "平均值=", sum/count}' data.txt
# 输出奇数行(结合NR)
awk 'NR % 2 == 1' file.txt
3. 文本重组
# 将逗号分隔文件转为JSON
awk -F, 'BEGIN {print "["} NR>1 {printf " {\"name\":\"%s\",\"age\":%d},\n", $1, $2} END {print "]"}' users.csv
# 合并多个文件的特定列
awk '{print FILENAME, $2}' file1.txt file2.txt
4. 高级处理
# 统计单词频率(忽略大小写)
awk '{for(i=1;i<=NF;i++) words[tolower($i)]++} END {for(w in words) print w, words[w]}' text.txt
# 处理多行记录(如空行分隔的块)
awk -v RS="" '{print "块", NR, "有", NF, "个字段"}' blocks.txt
六、内置函数
| 函数 | 说明 |
|---|---|
| 字符串处理 | |
length(str) | 返回字符串长度 |
substr(s, start, len) | 提取子字符串 |
split(s, arr, sep) | 分割字符串到数组 |
| 数学运算 | |
int(x) | 取整数部分 |
rand() | 生成0-1的随机数 |
| 时间处理 | |
systime() | 获取当前时间戳 |
strftime(format, timestamp) | 格式化时间 |
七、注意事项
-
字段分隔符:
- 使用
-F或BEGIN {FS="..."}指定分隔符(支持正则)。 - 处理CSV时注意引号包裹的字段(建议用
--csv或专用工具)。
- 使用
-
性能优化:
- 避免在大文件中频繁使用
print $0,明确指定输出字段。 - 使用数组时注意内存占用,及时删除无用元素(
delete array[key])。
- 避免在大文件中频繁使用
-
兼容性:
- 不同系统下的awk实现(如mawk、gawk)可能功能有差异,建议明确指定
#!/usr/bin/gawk -f。
- 不同系统下的awk实现(如mawk、gawk)可能功能有差异,建议明确指定
-
正则表达式:
- 使用
~和!~进行匹配(如$2 ~ /^[0-9]+$/)。
- 使用
通过灵活运用模式匹配、字段操作和脚本逻辑,awk可高效完成复杂文本处理任务。
11万+

被折叠的 条评论
为什么被折叠?



