AWK 函数调用
《AWK 函数调用》
🎯 学习目标
- 掌握 AWK 内置函数的使用方法(如
length,substr,index,split等) - 理解如何自定义函数实现模块化脚本编写
- 能在实际日志分析、系统信息提取中灵活调用函数
- 提升脚本可读性与复用性,为复杂数据处理打下基础
- 了解不同 Linux 发行版(Ubuntu、CentOS、EulerOS)对函数支持的差异
🔑 核心重点
| 类型 | 函数名 | 功能说明 |
|---|---|---|
| 字符串操作 | length(), substr(), index(), match() |
字符串长度、截取、查找、正则匹配 |
| 字段分割 | split() |
将字符串按分隔符拆分为数组 |
| 数学运算 | int(), sqrt(), rand(), srand() |
整数转换、平方根、随机数生成等 |
| 时间处理 | systime(), strftime() |
获取当前时间戳、格式化输出时间 |
| 自定义函数 | function name(...) { ... } |
自定义逻辑封装,提升代码结构 |
📚 详细讲解
一、内置函数详解
1. 字符串处理函数
✅ length([str])
返回字符串长度,不传参数时默认统计整行 $0
echo "hello world" | awk '{print length(), length($1)}'
输出:
11 5
✅ substr(str, start, [length])
从指定位置开始截取子字符串
awk 'BEGIN{print substr("Linux is awesome", 8, 2)}'
输出:
is
✅ index(str, find)
查找子字符串首次出现的位置(无则返回 0)
awk 'BEGIN{print index("Ubuntu", "bu")}'
输出:
2
✅ match(str, regex)
匹配正则表达式,返回起始位置,并设置 RSTART 和 RLENGTH
awk 'BEGIN{
str = "访问IP: 192.168.1.100";
if (match(str, /[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/))
print substr(str, RSTART, RLENGTH)
}'
输出:
192.168.1.100
2. 字段分割函数:split()
将字符串按指定分隔符拆分成数组
awk 'BEGIN{
str = "apple,banana,orange";
n = split(str, arr, ",");
for(i=1; i<=n; i++) print arr[i]
}'
输出:
apple
banana
orange
📌 实战应用:提取路径中的用户名
awk -F: '$3 >= 1000 {
split($6, path, "/");
print $1, path[3]
}' /etc/passwd
说明:
$6是用户的家目录路径(如/home/ubuntu)path[3]是用户名(ubuntu)
3. 数学函数
✅ int(x):取整
awk 'BEGIN{print int(3.1415)}'
输出:
3
✅ sqrt(x):平方根
awk 'BEGIN{print sqrt(16)}'
输出:
4
✅ rand():生成 0~1 的随机数
⚠️ 需要先调用 srand() 设置种子
awk 'BEGIN{srand(); print rand()}'
4. 时间处理函数
✅ systime():获取当前时间戳(秒级)
awk 'BEGIN{print systime()}'
✅ strftime(format, timestamp)
格式化输出时间,默认使用当前时间
awk 'BEGIN{
now = systime();
print strftime("%Y-%m-%d %H:%M:%S", now)
}'
输出示例:
2025-06-22 23:45:01
⏰ 常用格式符:
%Y:年份%m:月份%d:日期%H:小时(24h)%M:分钟%S:秒
二、实战案例:解析 Nginx 日志并格式化输出
场景:提取 IP、请求路径、状态码、时间,并格式化显示
假设日志如下:
192.168.1.100 - - [22/Jun/2025:12:34:56 +0800] "GET /index.html HTTP/1.1" 200 612 "-" "Mozilla/5.0"
我们写一个 AWK 脚本来美化输出:
awk '
{
# 提取时间字段并格式化
time_str = substr($4, 2); # 去掉开头的 [
split(time_str, t, ":"); # 拆分时间部分
date_part = t[1]; # 日期部分:22/Jun/2025
time_part = t[2] ":" t[3] ":" t[4];# 时间部分:12:34:56
# 输出格式化日志
printf "%-15s %-20s %-5s %s\n", $1, $7, $9, time_part
}' access.log
输出示例:
192.168.1.100 /index.html 200 12:34:56
📌 应用场景:
- 日志归档
- 审计日志展示
- 自动化监控报告生成
三、自定义函数:模块化你的脚本逻辑
语法:
function 函数名(参数列表) {
# 函数体
}
示例:判断是否是普通用户(UID >= 1000)
awk -F: '
function is_normal_user(uid) {
return uid >= 1000 ? "是" : "否"
}
NR > 1 {
print $1, is_normal_user($3)
}' /etc/passwd
输出示例:
root 否
daemon 否
ubuntu 是
四、实战案例:统计每个小时内访问量(带函数封装)
awk '
function get_hour(log_time, t) {
gsub(/\[|\+.*$/, "", log_time);
split(log_time, t, ":");
return t[2];
}
{
hour = get_hour($4);
count[hour]++;
}
END {
for (h in count)
print h ":00 ~ " h ":59", count[h], "次访问"
}' access.log
输出示例:
12:00 ~ 12:59 150 次访问
13:00 ~ 13:59 200 次访问
📌 技巧说明:
- 使用了函数封装提取小时逻辑
- 可以轻松扩展成“每天”、“每周”统计
五、不同 Linux 发行版注意事项(Ubuntu vs CentOS vs EulerOS)
| 特性 | Ubuntu | CentOS | EulerOS |
|---|---|---|---|
| 默认 awk | gawk | gawk | gawk |
| 支持自定义函数 | ✅ | ✅ | ✅ |
支持 strftime() |
✅(gawk) | ✅ | ✅ |
支持 PROCINFO["sorted_in"] |
✅(gawk 4.0+) | ✅ | ✅ |
| 日志文件位置 | /var/log/syslog |
/var/log/messages |
/var/log/messages |
📌 小贴士:
- 在 CentOS/EulerOS 上查看
/var/log/messages需要管理员权限,建议使用sudo awk ... - 不同系统的日志格式会影响字段提取逻辑,请先观察几行日志结构再写脚本
六、调试与优化建议
| 技巧 | 说明 |
|---|---|
print $0 |
打印原始行内容,确认是否符合预期 |
print NF |
查看字段数量是否正确 |
print substr($0, 1, 50) |
查看前几个字符,辅助定位字段偏移 |
| `head -n 5 file | awk '...'` |
BEGIN{FS=","} |
设置合适的字段分隔符提升可读性 |
function debug(...) |
自定义调试函数统一输出格式 |
✅ 总结
掌握 AWK 的函数调用能力,是迈向高级脚本开发的重要一步。通过使用内置函数和自定义函数,你可以:
- 快速处理文本、提取关键信息
- 实现复杂的逻辑封装与复用
- 构建高效、可维护的日志分析工具
无论你是想做服务器日志分析、自动化运维脚本开发,还是系统安全审计,AWK 的函数机制都能为你提供强大支撑。
继续练习真实日志文件,结合 grep、sort、uniq 等命令,你将成为一名真正的 Linux 文本处理高手!🚀🔥

浙公网安备 33010602011771号