LinuxAWK高级用法深度解析

admin 2026-01-18 02:33:32 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: ThisdocumentoffersadeepdiveintoadvancedAWKprogramming,coveringmulti-dimensionalarrays,functionalprogrammingparadigmslikerecursionandmemoization,andsophisticatedstringmanipulationusingregex.Itdemonstratespracticalapplicationsthroughscriptsforloganalysisandconfigurationparsing,showcasingAWK’spowerfordataprocessingandsystemautomation.TheguideemphasizesleveragingAWKasacompletelanguageforcomplexstatisticaltasksandtexttransformation,providingactionableexamplesforoperationsandsecurityanalysis. 综合评分: 90 文章分类: 安全工具,安全运营,实战经验


cover_image

Linux AWK 高级用法深度解析

原创

刘军军 刘军军

运维星火燎原

2026年1月18日 00:00 山西

一、AWK 高级特性概述

AWK 不仅仅是一个文本处理工具,它是一门完整的编程语言。以下是 AWK 的高级特性分类:

| | | | | — | — | — | | 特性类别 | 主要功能 | 应用场景 | | 数组处理 | 关联数组、多维数组 | 数据统计、分组汇总 | | 函数编程 | 内置函数、自定义函数 | 复杂计算、字符串处理 | | 模式匹配 | 正则表达式、范围模式 | 日志分析、数据提取 | | 系统交互 | 执行系统命令、文件操作 | 系统管理、自动化脚本 | | 高级I/O | 多文件处理、管道 | 大数据处理、报表生成 |

二、高级数组处理

2.1 关联数组深度应用

#!/bin/bash
# awk-advanced-arrays.sh

echo"=== AWK 高级数组处理 ==="

# 创建复杂的测试数据
cat > sales_data.txt <<&nbsp;'EOF'
2024-01-15,John,Electronics,1200.50,New York
2024-01-15,Jane,Clothing,850.75,Los Angeles
2024-01-15,Bob,Electronics,2100.00,New York
2024-01-16,John,Clothing,450.25,New York
2024-01-16,Jane,Electronics,1800.00,Los Angeles
2024-01-16,Alice,Books,320.50,Chicago
2024-01-17,Bob,Books,280.75,New York
2024-01-17,John,Electronics,950.00,New York
2024-01-17,Jane,Clothing,675.50,Los Angeles
EOF

echo"📊 销售数据:"
column -t -s','&nbsp;sales_data.txt
echo"========================================"

# 1. 多维统计
echo"1. 📈 多维数据统计 (城市×品类):"
awk -F&nbsp;',''
{
&nbsp; &nbsp; date = $1
&nbsp; &nbsp; salesperson = $2
&nbsp; &nbsp; category = $3
&nbsp; &nbsp; amount = $4
&nbsp; &nbsp; city = $5

&nbsp; &nbsp; # 多维统计
&nbsp; &nbsp; sales_by_city_category[city][category] += amount
&nbsp; &nbsp; sales_by_date_city[date][city] += amount
&nbsp; &nbsp; salesperson_total[salesperson] += amount
&nbsp; &nbsp; daily_total[date] += amount

&nbsp; &nbsp; # 计数
&nbsp; &nbsp; transaction_count[city][category]++
}
END {
&nbsp; &nbsp; print "=== 城市×品类销售统计 ==="
&nbsp; &nbsp; for (city in sales_by_city_category) {
&nbsp; &nbsp; &nbsp; &nbsp; for (category in sales_by_city_category[city]) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; printf "%-12s %-12s $%8.2f (%d笔)\n",
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;city, category,
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;sales_by_city_category[city][category],
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;transaction_count[city][category]
&nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; }

&nbsp; &nbsp; print "\n=== 销售员业绩排名 ==="
&nbsp; &nbsp; # 使用asorti对关联数组的索引进行排序
&nbsp; &nbsp; n = asorti(salesperson_total, sorted_salespersons)
&nbsp; &nbsp; for (i = n; i >= 1; i--) {
&nbsp; &nbsp; &nbsp; &nbsp; person = sorted_salespersons[i]
&nbsp; &nbsp; &nbsp; &nbsp; printf "%-8s: $%8.2f\n", person, salesperson_total[person]
&nbsp; &nbsp; }
}'&nbsp;sales_data.txt

# 2. 数组的数组
echo&nbsp;-e&nbsp;"\n2. 🎯 复杂数据结构:"
awk -F&nbsp;',''
{
&nbsp; &nbsp; city = $5
&nbsp; &nbsp; category = $3
&nbsp; &nbsp; amount = $4

&nbsp; &nbsp; # 创建城市→品类→金额的嵌套结构
&nbsp; &nbsp; if (!(city in city_data)) {
&nbsp; &nbsp; &nbsp; &nbsp; city_data[city]["total"] = 0
&nbsp; &nbsp; &nbsp; &nbsp; city_data[city]["count"] = 0
&nbsp; &nbsp; &nbsp; &nbsp; city_data[city]["categories"] = 0
&nbsp; &nbsp; }

&nbsp; &nbsp; city_data[city]["total"] += amount
&nbsp; &nbsp; city_data[city]["count"]++

&nbsp; &nbsp; if (!(category in city_data[city])) {
&nbsp; &nbsp; &nbsp; &nbsp; city_data[city][category] = 0
&nbsp; &nbsp; &nbsp; &nbsp; city_data[city]["categories"]++
&nbsp; &nbsp; }
&nbsp; &nbsp; city_data[city][category] += amount
}
END {
&nbsp; &nbsp; print "=== 城市详细统计 ==="
&nbsp; &nbsp; for (city in city_data) {
&nbsp; &nbsp; &nbsp; &nbsp; printf "\n🏙️ &nbsp;城市: %s\n", city
&nbsp; &nbsp; &nbsp; &nbsp; printf " &nbsp; 总销售额: $%.2f\n", city_data[city]["total"]
&nbsp; &nbsp; &nbsp; &nbsp; printf " &nbsp; 交易笔数: %d\n", city_data[city]["count"]
&nbsp; &nbsp; &nbsp; &nbsp; printf " &nbsp; 品类数量: %d\n", city_data[city]["categories"]

&nbsp; &nbsp; &nbsp; &nbsp; # 输出每个品类的销售
&nbsp; &nbsp; &nbsp; &nbsp; for (key in city_data[city]) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (key != "total" && key != "count" && key != "categories") {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; printf " &nbsp; %-12s: $%8.2f\n", key, city_data[city][key]
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; }
}'&nbsp;sales_data.txt

# 清理
rm sales_data.txt

2.2 数组函数和操作

#!/bin/bash
# awk-array-functions.sh

echo"=== AWK 数组函数高级应用 ==="

# 创建测试数据
cat > student_scores.txt <<&nbsp;'EOF'
Alice:Math:95:Physics:88:Chemistry:92
Bob:Math:78:Physics:85:Chemistry:90
Carol:Math:92:Physics:96:Chemistry:94
David:Math:85:Physics:82:Chemistry:88
Eve:Math:91:Physics:89:Chemistry:93
EOF

echo"📊 学生成绩数据:"
cat student_scores.txt
echo"========================================"

# 1. 数组长度和遍历
echo"1. 📏 数组操作函数:"
awk -F&nbsp;':''
{
&nbsp; &nbsp; student = $1
&nbsp; &nbsp; # 动态创建科目→成绩的映射
&nbsp; &nbsp; for (i = 2; i <= NF; i += 2) {
&nbsp; &nbsp; &nbsp; &nbsp; subject = $i
&nbsp; &nbsp; &nbsp; &nbsp; score = $(i+1)
&nbsp; &nbsp; &nbsp; &nbsp; scores[student][subject] = score
&nbsp; &nbsp; &nbsp; &nbsp; subjects[subject]++ &nbsp;# 记录所有科目
&nbsp; &nbsp; }
}
END {
&nbsp; &nbsp; print "=== 学生成绩统计 ==="

&nbsp; &nbsp; # 获取学生数量
&nbsp; &nbsp; student_count = length(scores)
&nbsp; &nbsp; printf "学生数量: %d\n", student_count

&nbsp; &nbsp; # 获取科目数量
&nbsp; &nbsp; subject_count = length(subjects)
&nbsp; &nbsp; printf "科目数量: %d\n", subject_count

&nbsp; &nbsp; # 遍历所有学生
&nbsp; &nbsp; print "\n📋 学生列表:"
&nbsp; &nbsp; for (student in scores) {
&nbsp; &nbsp; &nbsp; &nbsp; printf "%-8s", student
&nbsp; &nbsp; }
&nbsp; &nbsp; print ""

&nbsp; &nbsp; # 遍历所有科目并计算平均分
&nbsp; &nbsp; print "\n📊 科目平均分:"
&nbsp; &nbsp; for (subject in subjects) {
&nbsp; &nbsp; &nbsp; &nbsp; total = 0
&nbsp; &nbsp; &nbsp; &nbsp; count = 0
&nbsp; &nbsp; &nbsp; &nbsp; for (student in scores) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (subject in scores[student]) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; total += scores[student][subject]
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; count++
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; &nbsp; &nbsp; avg = total / count
&nbsp; &nbsp; &nbsp; &nbsp; printf "%-10s: %.1f\n", subject, avg
&nbsp; &nbsp; }

&nbsp; &nbsp; # 删除数组元素示例
&nbsp; &nbsp; print "\n🗑️ &nbsp;删除Bob的数据后:"
&nbsp; &nbsp; delete scores["Bob"]
&nbsp; &nbsp; for (student in scores) {
&nbsp; &nbsp; &nbsp; &nbsp; printf "%-8s", student
&nbsp; &nbsp; }
&nbsp; &nbsp; print ""
}'&nbsp;student_scores.txt

# 2. 数组复制和比较
echo&nbsp;-e&nbsp;"\n2. 🔄 数组的复制和比较:"
awk&nbsp;'
BEGIN {
&nbsp; &nbsp; # 创建源数组
&nbsp; &nbsp; source["Math"] = 90
&nbsp; &nbsp; source["Physics"] = 85
&nbsp; &nbsp; source["Chemistry"] = 92

&nbsp; &nbsp; print "源数组:"
&nbsp; &nbsp; for (key in source) {
&nbsp; &nbsp; &nbsp; &nbsp; printf " &nbsp;%s: %d\n", key, source[key]
&nbsp; &nbsp; }

&nbsp; &nbsp; # 数组复制(手动)
&nbsp; &nbsp; print "\n复制数组:"
&nbsp; &nbsp; for (key in source) {
&nbsp; &nbsp; &nbsp; &nbsp; copy[key] = source[key]
&nbsp; &nbsp; &nbsp; &nbsp; printf " &nbsp;%s: %d\n", key, copy[key]
&nbsp; &nbsp; }

&nbsp; &nbsp; # 检查数组是否相等
&nbsp; &nbsp; is_equal = 1
&nbsp; &nbsp; for (key in source) {
&nbsp; &nbsp; &nbsp; &nbsp; if (!(key in copy) || source[key] != copy[key]) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; is_equal = 0
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break
&nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; }
&nbsp; &nbsp; if (length(source) != length(copy)) {
&nbsp; &nbsp; &nbsp; &nbsp; is_equal = 0
&nbsp; &nbsp; }

&nbsp; &nbsp; print "\n数组相等:", is_equal ? "是" : "否"

&nbsp; &nbsp; # 修改副本并再次比较
&nbsp; &nbsp; copy["Math"] = 95
&nbsp; &nbsp; is_equal_after = 1
&nbsp; &nbsp; for (key in source) {
&nbsp; &nbsp; &nbsp; &nbsp; if (!(key in copy) || source[key] != copy[key]) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; is_equal_after = 0
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break
&nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; }
&nbsp; &nbsp; print "修改后相等:", is_equal_after ? "是" : "否"
}'

# 清理
rm student_scores.txt

三、高级函数编程

3.1 自定义函数深度应用

#!/bin/bash
# awk-custom-functions.sh

echo"=== AWK 自定义函数高级应用 ==="

# 创建金融交易数据
cat > transactions.txt <<&nbsp;'EOF'
2024-01-15T10:30:25,INV-001,John Doe,1500.00,COMPLETED
2024-01-15T11:15:30,INV-002,Jane Smith,2750.50,COMPLETED
2024-01-15T12:45:15,INV-003,Bob Johnson,980.75,PENDING
2024-01-15T14:20:40,INV-004,Alice Brown,3200.25,COMPLETED
2024-01-15T15:55:10,INV-005,Charlie Wilson,450.00,FAILED
EOF

echo"💳 交易数据:"
cat transactions.txt
echo"========================================"

# 1. 自定义函数库
echo"1. 🛠️ &nbsp;自定义函数库实现:"
awk -F&nbsp;',''
# 函数定义必须在BEGIN之前
function format_amount(amount) {
&nbsp; &nbsp; if (amount >= 1000) {
&nbsp; &nbsp; &nbsp; &nbsp; return sprintf("$%\'d", amount)
&nbsp; &nbsp; } else {
&nbsp; &nbsp; &nbsp; &nbsp; return sprintf("$%.2f", amount)
&nbsp; &nbsp; }
}

function get_status_color(status) {
&nbsp; &nbsp; switch (status) {
&nbsp; &nbsp; &nbsp; &nbsp; case "COMPLETED":
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return "✅"
&nbsp; &nbsp; &nbsp; &nbsp; case "PENDING":
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return "⏳"
&nbsp; &nbsp; &nbsp; &nbsp; case "FAILED":
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return "❌"
&nbsp; &nbsp; &nbsp; &nbsp; default:
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return "❓"
&nbsp; &nbsp; }
}

function parse_timestamp(timestamp, &nbsp; &nbsp;datetime, date, time) {
&nbsp; &nbsp; split(timestamp, datetime, "T")
&nbsp; &nbsp; date = datetime[1]
&nbsp; &nbsp; time = datetime[2]
&nbsp; &nbsp; gsub(/-/, "/", date) &nbsp;# 转换日期格式
&nbsp; &nbsp; return date "" time
}

function calculate_tax(amount, rate) {
&nbsp; &nbsp; return amount * rate
}

function generate_report_line(transaction, &nbsp; &nbsp;fields) {
&nbsp; &nbsp; split(transaction, fields, ",")
&nbsp; &nbsp; return sprintf("%s %s %-12s %12s %s",
&nbsp; &nbsp; &nbsp; &nbsp; get_status_color(fields[5]),
&nbsp; &nbsp; &nbsp; &nbsp; parse_timestamp(fields[1]),
&nbsp; &nbsp; &nbsp; &nbsp; fields[3],
&nbsp; &nbsp; &nbsp; &nbsp; format_amount(fields[4]),
&nbsp; &nbsp; &nbsp; &nbsp; fields[5])
}

# 主处理逻辑
{
&nbsp; &nbsp; # 使用自定义函数处理数据
&nbsp; &nbsp; formatted = generate_report_line($0)
&nbsp; &nbsp; print formatted

&nbsp; &nbsp; # 统计信息
&nbsp; &nbsp; total_amount +=&nbsp;$4
&nbsp; &nbsp; status_count[$5]++
}
END {
&nbsp; &nbsp; print "\n=== 交易统计 ==="
&nbsp; &nbsp; printf "总交易金额: %s\n", format_amount(total_amount)
&nbsp; &nbsp; printf "平均交易额: %s\n", format_amount(total_amount / NR)

&nbsp; &nbsp; print "\n交易状态分布:"
&nbsp; &nbsp; for (status in status_count) {
&nbsp; &nbsp; &nbsp; &nbsp; printf "%-10s: %d 笔\n", status, status_count[status]
&nbsp; &nbsp; }

&nbsp; &nbsp; # 计算税费示例
&nbsp; &nbsp; tax_rate = 0.08
&nbsp; &nbsp; tax_amount = calculate_tax(total_amount, tax_rate)
&nbsp; &nbsp; printf "\n税费估算 (%.1f%%): %s\n", tax_rate * 100, format_amount(tax_amount)
}' transactions.txt

# 2. 递归函数和数学计算
echo -e "\n2. 🔢 高级数学函数:"
awk '
# 递归计算阶乘
function factorial(n) {
&nbsp; &nbsp; if (n <= 1) return 1
&nbsp; &nbsp; return n * factorial(n - 1)
}

# 计算组合数 C(n, k)
function combination(n, k) {
&nbsp; &nbsp; if (k < 0 || k > n) return 0
&nbsp; &nbsp; return factorial(n) / (factorial(k) * factorial(n - k))
}

# 计算排列数 P(n, k)
function permutation(n, k) {
&nbsp; &nbsp; if (k < 0 || k > n) return 0
&nbsp; &nbsp; return factorial(n) / factorial(n - k)
}

# 主程序
BEGIN {
&nbsp; &nbsp; print "=== 高级数学计算 ==="

&nbsp; &nbsp; # 测试阶乘
&nbsp; &nbsp; print "阶乘计算:"
&nbsp; &nbsp; for (i = 1; i <= 10; i++) {
&nbsp; &nbsp; &nbsp; &nbsp; printf "%-2d! = %d\n", i, factorial(i)
&nbsp; &nbsp; }

&nbsp; &nbsp; # 测试组合数
&nbsp; &nbsp; print "\n组合数计算 C(5, k):"
&nbsp; &nbsp; for (k = 0; k <= 5; k++) {
&nbsp; &nbsp; &nbsp; &nbsp; printf "C(5, %d) = %d\n", k, combination(5, k)
&nbsp; &nbsp; }

&nbsp; &nbsp; # 测试排列数
&nbsp; &nbsp; print "\n排列数计算 P(5, k):"
&nbsp; &nbsp; for (k = 0; k <= 5; k++) {
&nbsp; &nbsp; &nbsp; &nbsp; printf "P(5, %d) = %d\n", k, permutation(5, k)
&nbsp; &nbsp; }
}'

# 清理
rm transactions.txt

3.2 函数式编程特性

#!/bin/bash
# awk-functional-programming.sh

echo"=== AWK 函数式编程特性 ==="

# 创建数据处理示例
cat > numbers.txt <<&nbsp;'EOF'
10 25 38 42 15 67 89 53 21 74
35 18 92 57 63 29 81 46 12 95
EOF

echo"🔢 数字数据:"
cat numbers.txt
echo"========================================"

# 1. 高阶函数应用
echo"1. 🎯 高阶函数模式:"
awk&nbsp;'
# 映射函数 (map)
function map(array, func, &nbsp; &nbsp;i, result) {
&nbsp; &nbsp; for (i in array) {
&nbsp; &nbsp; &nbsp; &nbsp; result[i] = func(array[i])
&nbsp; &nbsp; }
&nbsp; &nbsp; return result
}

# 过滤函数 (filter)
function filter(array, func, &nbsp; &nbsp;i, result, count) {
&nbsp; &nbsp; count = 0
&nbsp; &nbsp; for (i in array) {
&nbsp; &nbsp; &nbsp; &nbsp; if (func(array[i])) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; result[++count] = array[i]
&nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; }
&nbsp; &nbsp; return result
}

# 归约函数 (reduce)
function reduce(array, func, initial, &nbsp; &nbsp;i, result) {
&nbsp; &nbsp; result = initial
&nbsp; &nbsp; for (i in array) {
&nbsp; &nbsp; &nbsp; &nbsp; result = func(result, array[i])
&nbsp; &nbsp; }
&nbsp; &nbsp; return result
}

# 实用函数
function square(x) { return x * x }
function is_even(x) { return x % 2 == 0 }
function sum(a, b) { return a + b }
function max(a, b) { return a > b ? a : b }

BEGIN {
&nbsp; &nbsp; # 创建测试数组
&nbsp; &nbsp; numbers[1] = 10; numbers[2] = 25; numbers[3] = 38; numbers[4] = 42
&nbsp; &nbsp; numbers[5] = 15; numbers[6] = 67; numbers[7] = 89; numbers[8] = 53
&nbsp; &nbsp; numbers[9] = 21; numbers[10] = 74

&nbsp; &nbsp; print "原始数组:", array_to_string(numbers)

&nbsp; &nbsp; # 使用map
&nbsp; &nbsp; squared = map(numbers, square)
&nbsp; &nbsp; print "平方映射:", array_to_string(squared)

&nbsp; &nbsp; # 使用filter
&nbsp; &nbsp; evens = filter(numbers, is_even)
&nbsp; &nbsp; print "偶数过滤:", array_to_string(evens)

&nbsp; &nbsp; # 使用reduce
&nbsp; &nbsp; total = reduce(numbers, sum, 0)
&nbsp; &nbsp; maximum = reduce(numbers, max, numbers[1])

&nbsp; &nbsp; print "总和归约:", total
&nbsp; &nbsp; print "最大值归约:", maximum

&nbsp; &nbsp; # 函数组合: 先过滤偶数,再求平方,最后求和
&nbsp; &nbsp; result = reduce(map(filter(numbers, is_even), square), sum, 0)
&nbsp; &nbsp; print "组合操作结果:", result
}

function array_to_string(arr, &nbsp; &nbsp;i, str) {
&nbsp; &nbsp; str = ""
&nbsp; &nbsp; for (i = 1; i <= length(arr); i++) {
&nbsp; &nbsp; &nbsp; &nbsp; str = str (str ? ", " : "") arr[i]
&nbsp; &nbsp; }
&nbsp; &nbsp; return "[" str "]"
}'

# 2. 闭包和柯里化
echo&nbsp;-e&nbsp;"\n2. 🔗 闭包和柯里化模式:"
awk&nbsp;'
# 柯里化函数:创建特定乘数的函数
function multiplier(factor) {
&nbsp; &nbsp; return function(x) { return x * factor }
}

# 闭包示例:计数器工厂
function counter(initial) {
&nbsp; &nbsp; var count = initial
&nbsp; &nbsp; return function() { return ++count }
}

# 记忆化函数
function memoize(func, &nbsp; &nbsp;cache) {
&nbsp; &nbsp; return function(arg) {
&nbsp; &nbsp; &nbsp; &nbsp; if (!(arg in cache)) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cache[arg] = func(arg)
&nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; &nbsp; &nbsp; return cache[arg]
&nbsp; &nbsp; }
}

BEGIN {
&nbsp; &nbsp; print "=== 函数式编程模式 ==="

&nbsp; &nbsp; # 柯里化应用
&nbsp; &nbsp; double = multiplier(2)
&nbsp; &nbsp; triple = multiplier(3)

&nbsp; &nbsp; print "柯里化测试:"
&nbsp; &nbsp; printf "double(5) = %d\n", double(5)
&nbsp; &nbsp; printf "triple(5) = %d\n", triple(5)

&nbsp; &nbsp; # 闭包应用
&nbsp; &nbsp; count1 = counter(0)
&nbsp; &nbsp; count2 = counter(100)

&nbsp; &nbsp; print "\n闭包计数器:"
&nbsp; &nbsp; print "计数器1:", count1(), count1(), count1()
&nbsp; &nbsp; print "计数器2:", count2(), count2(), count2()

&nbsp; &nbsp; # 记忆化应用
&nbsp; &nbsp; memoized_factorial = memoize(function(n) {
&nbsp; &nbsp; &nbsp; &nbsp; if (n <= 1) return 1
&nbsp; &nbsp; &nbsp; &nbsp; return n * memoized_factorial(n - 1)
&nbsp; &nbsp; })

&nbsp; &nbsp; print "\n记忆化阶乘:"
&nbsp; &nbsp; print "10! =", memoized_factorial

四、AWK 复杂字符串处理深度指南

1.AWK 字符串处理核心功能

AWK 提供了强大的字符串处理能力,以下是主要功能分类:

| | | | | — | — | — | | 功能类别 | 主要函数 | 应用场景 | | 基础操作 | length, substr, index | 字符串长度、子串提取、位置查找 | | 模式匹配 | match, gensub, gsub | 正则匹配、全局替换 | | 分割合并 | split, sprintf | 字符串分割、格式化输出 | | 转换处理 | toupper, tolower, strtonum | 大小写转换、字符串转数字 | | 编码处理 | ENVIRON, system | 环境变量、系统调用 |

2.基础字符串操作

2.1 常用字符串函数

#!/bin/bash
# awk-string-basics.sh

echo"=== AWK 基础字符串操作 ==="

# 创建测试数据
cat > string_data.txt <<&nbsp;'EOF'
Hello World
AWK Programming
Linux System Administration
[email protected]
+1-555-0123
2024-01-15T14:30:00
EOF

echo"📝 测试字符串数据:"
cat string_data.txt
echo"========================================"

# 1. 基础字符串函数
echo"1. 🔧 基础字符串函数演示:"
awk&nbsp;'
{
&nbsp; &nbsp; print "原始字符串:", $0
&nbsp; &nbsp; print "字符串长度:", length($0)

&nbsp; &nbsp; # substr 提取子串
&nbsp; &nbsp; if (length($0) >= 5) {
&nbsp; &nbsp; &nbsp; &nbsp; print "前5个字符:", substr($0, 1, 5)
&nbsp; &nbsp; &nbsp; &nbsp; print "后5个字符:", substr($0, length($0)-4, 5)
&nbsp; &nbsp; }

&nbsp; &nbsp; # index 查找位置
&nbsp; &nbsp; pos = index($0, " ")
&nbsp; &nbsp; if (pos > 0) {
&nbsp; &nbsp; &nbsp; &nbsp; print "第一个空格位置:", pos
&nbsp; &nbsp; }

&nbsp; &nbsp; print "---"
}'&nbsp;string_data.txt

# 2. 大小写转换和字符操作
echo&nbsp;-e&nbsp;"\n2. 🔄 大小写和字符处理:"
awk&nbsp;'
{
&nbsp; &nbsp; print "原始:", $0
&nbsp; &nbsp; print "大写:", toupper($0)
&nbsp; &nbsp; print "小写:", tolower($0)

&nbsp; &nbsp; # 首字母大写
&nbsp; &nbsp; if ($0 != "") {
&nbsp; &nbsp; &nbsp; &nbsp; first_char = substr($0, 1, 1)
&nbsp; &nbsp; &nbsp; &nbsp; rest_chars = substr($0, 2)
&nbsp; &nbsp; &nbsp; &nbsp; print "首字母大写:", toupper(first_char) tolower(rest_chars)
&nbsp; &nbsp; }
&nbsp; &nbsp; print "---"
}'&nbsp;string_data.txt

3.高级模式匹配

3.1 正则表达式深度应用

#!/bin/bash
# awk-regex-advanced.sh

echo"=== AWK 高级正则表达式处理 ==="

# 创建复杂文本数据
cat > complex_text.txt <<&nbsp;'EOF'
Contact: [email protected], phone: +1-555-0123
Meeting: 2024-01-15T14:30:00 at Office-123
Price:&nbsp;$1,299.99, Discount: 15%
IP: 192.168.1.1, Mask: 255.255.255.0
JSON: {"name":&nbsp;"John",&nbsp;"age": 30,&nbsp;"active":&nbsp;true}
EOF

echo"📄 复杂文本数据:"
cat complex_text.txt
echo"========================================"

# 1. match 函数的高级用法
echo"1. 🎯 match 函数捕获组:"
awk&nbsp;'
{
&nbsp; &nbsp; # 匹配邮箱并提取用户名和域名
&nbsp; &nbsp; if (match($0, /([a-zA-Z0-9._%+-]+)@([a-zA-Z0-9.-]+\.[a-zA-Z]{2,})/, arr)) {
&nbsp; &nbsp; &nbsp; &nbsp; print "📧 邮箱匹配:"
&nbsp; &nbsp; &nbsp; &nbsp; print " &nbsp;完整邮箱:", arr[0]
&nbsp; &nbsp; &nbsp; &nbsp; print " &nbsp;用户名:", arr[1]
&nbsp; &nbsp; &nbsp; &nbsp; print " &nbsp;域名:", arr[2]
&nbsp; &nbsp; }

&nbsp; &nbsp; # 匹配价格格式
&nbsp; &nbsp; if (match($0, /\$[0-9,]+(\.[0-9]{2})?/, arr)) {
&nbsp; &nbsp; &nbsp; &nbsp; print "💰 价格匹配:", arr[0]
&nbsp; &nbsp; }

&nbsp; &nbsp; # 匹配日期时间
&nbsp; &nbsp; if (match($0, /[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}/, arr)) {
&nbsp; &nbsp; &nbsp; &nbsp; print "📅 时间匹配:", arr[0]
&nbsp; &nbsp; }

&nbsp; &nbsp; print "---"
}'&nbsp;complex_text.txt

# 2. gensub 高级替换
echo&nbsp;-e&nbsp;"\n2. 🔄 gensub 高级替换模式:"
awk&nbsp;'
{
&nbsp; &nbsp; original = $0

&nbsp; &nbsp; # 使用gensub进行复杂替换
&nbsp; &nbsp; # 替换邮箱域名
&nbsp; &nbsp; email_replaced = gensub(/([a-zA-Z0-9._%+-]+)@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/,
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;"\\[email protected]", "g", $0)

&nbsp; &nbsp; # 隐藏电话号码
&nbsp; &nbsp; phone_replaced = gensub(/\+?[0-9-]{10,}/,
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;"***-***-****", "g", email_replaced)

&nbsp; &nbsp; # 格式化价格
&nbsp; &nbsp; formatted = gensub(/\$([0-9,]+(\.[0-9]{2})?)/,
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "💰 \\1", "g", phone_replaced)

&nbsp; &nbsp; print "原始:", original
&nbsp; &nbsp; print "处理后:", formatted
&nbsp; &nbsp; print "---"
}'&nbsp;complex_text.txt

3.2 多模式匹配和处理

#!/bin/bash
# awk-multi-pattern.sh

echo"=== AWK 多模式匹配处理 ==="

# 创建多模式测试数据
cat > multi_pattern.txt <<&nbsp;'EOF'
ERROR: Database connection failed at 2024-01-15 14:30
WARNING: High memory usage: 85%
INFO: User login: [email protected]
DEBUG: Query executed&nbsp;in&nbsp;150ms
ERROR: File not found: /path/to/file.txt
INFO: Backup completed successfully
EOF

echo"📋 日志模式数据:"
cat multi_pattern.txt
echo"========================================"

# 复杂多模式匹配和提取
awk&nbsp;'
{
&nbsp; &nbsp; # 定义匹配模式数组
&nbsp; &nbsp; patterns["ERROR"] = "❌"
&nbsp; &nbsp; patterns["WARNING"] = "⚠️ "
&nbsp; &nbsp; patterns["INFO"] = "ℹ️ "
&nbsp; &nbsp; patterns["DEBUG"] = "🐛"

&nbsp; &nbsp; # 检查每种模式
&nbsp; &nbsp; for (pattern in patterns) {
&nbsp; &nbsp; &nbsp; &nbsp; if (match($0, pattern ": ([^:]+):? (.+)", arr)) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print patterns[pattern] " " pattern ":"
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print " &nbsp; 消息:", arr[2]

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # 提取额外信息
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (pattern == "ERROR" && match($0, /at ([0-9:-]+)/, time_arr)) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print " &nbsp; 时间:", time_arr[1]
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (match($0, /([0-9]+)%/, percent_arr)) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print " &nbsp; 百分比:", percent_arr[1] "%"
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (match($0, /in ([0-9]+ms)/, time_arr)) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print " &nbsp; 耗时:", time_arr[1]
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break
&nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; }
}'&nbsp;multi_pattern.txt

4.字符串分割和重组

4.1 高级 split 函数应用

#!/bin/bash
# awk-split-advanced.sh

echo"=== AWK 高级字符串分割 ==="

# 创建需要分割的数据
cat > split_data.txt <<&nbsp;'EOF'
name=John Doe;age=30;city=New York;[email protected]
name=Jane Smith;age=25;city=Los Angeles;phone=555-0123
name=Bob Wilson;age=35;department=Engineering;salary=75000
EOF

echo"🔗 键值对数据:"
cat split_data.txt
echo"========================================"

# 1. 复杂分割和数据结构构建
echo"1. 🧩 多级分割和数据结构:"
awk -F&nbsp;';''
{
&nbsp; &nbsp; print "处理记录:", NR

&nbsp; &nbsp; # 第一级分割:分号分隔
&nbsp; &nbsp; for (i = 1; i <= NF; i++) {
&nbsp; &nbsp; &nbsp; &nbsp; # 第二级分割:等号分隔
&nbsp; &nbsp; &nbsp; &nbsp; split($i, keyvalue, "=")
&nbsp; &nbsp; &nbsp; &nbsp; if (length(keyvalue) >= 2) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; key = keyvalue[1]
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; value = keyvalue[2]

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # 存储到多维数组
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; data[NR][key] = value
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; all_keys[key]++ &nbsp;# 记录所有出现的key
&nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; }
}
END {
&nbsp; &nbsp; print "\n📊 数据统计:"

&nbsp; &nbsp; # 输出表格格式
&nbsp; &nbsp; printf "%-6s", "Record"
&nbsp; &nbsp; for (key in all_keys) {
&nbsp; &nbsp; &nbsp; &nbsp; printf "%-15s", key
&nbsp; &nbsp; }
&nbsp; &nbsp; print ""

&nbsp; &nbsp; # 输出分隔线
&nbsp; &nbsp; printf "%-6s", "------"
&nbsp; &nbsp; for (key in all_keys) {
&nbsp; &nbsp; &nbsp; &nbsp; printf "%-15s", "---------------"
&nbsp; &nbsp; }
&nbsp; &nbsp; print ""

&nbsp; &nbsp; # 输出数据
&nbsp; &nbsp; for (record in data) {
&nbsp; &nbsp; &nbsp; &nbsp; printf "%-6d", record
&nbsp; &nbsp; &nbsp; &nbsp; for (key in all_keys) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; value = (key in data[record]) ? data[record][key] : "N/A"
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; printf "%-15s", value
&nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; &nbsp; &nbsp; print ""
&nbsp; &nbsp; }
}'&nbsp;split_data.txt

# 2. CSV 和复杂分隔符处理
echo&nbsp;-e&nbsp;"\n2. 📋 CSV 和复杂格式处理:"
cat > complex_csv.txt <<&nbsp;'EOF'
"John Doe",30,"New York, NY","[email protected]"
"Jane Smith",25,"Los Angeles, CA","[email protected]"
"Bob ""The Boss"" Johnson",35,"Chicago, IL","[email protected]"
EOF

awk&nbsp;'
BEGIN {
&nbsp; &nbsp; FPAT = "([^,]*)|(\"[^\"]+\")" &nbsp;# 处理带引号的字段
}
{
&nbsp; &nbsp; print "记录", NR ":"
&nbsp; &nbsp; for (i = 1; i <= NF; i++) {
&nbsp; &nbsp; &nbsp; &nbsp; # 移除引号
&nbsp; &nbsp; &nbsp; &nbsp; gsub(/^\"|\"$/, "", $i)
&nbsp; &nbsp; &nbsp; &nbsp; gsub(/\"\"/, "\"", $i) &nbsp;# 处理转义引号
&nbsp; &nbsp; &nbsp; &nbsp; printf " &nbsp;字段%d: %s\n", i, $i
&nbsp; &nbsp; }
&nbsp; &nbsp; print "---"
}'&nbsp;complex_csv.txt

5.实战应用案例

5.1 日志文件分析

#!/bin/bash
# awk-log-analysis.sh

echo&nbsp;"=== AWK 日志文件分析实战 ==="

# 创建模拟的Web服务器日志
cat > web_server.log <<&nbsp;'EOF'
192.168.1.1&nbsp;- - [15/Jan/2024:10:30:25 +0800] "GET /index.html HTTP/1.1" 200 1524 "http://example.com" "Mozilla/5.0"
192.168.1.2 - - [15/Jan/2024:10:30:26 +0800] "GET&nbsp;/about.html HTTP/1.1" 200 2345 "http://example.com" "Mozilla/5.0"
192.168.1.3 - - [15/Jan/2024:10:30:27 +0800] "POST&nbsp;/login HTTP/1.1" 302 0 "http://example.com" "Chrome/91.0"
192.168.1.1 - - [15/Jan/2024:10:30:28 +0800] "GET&nbsp;/products HTTP/1.1" 200 5678 "http://example.com" "Firefox/89.0"
192.168.1.4 - - [15/Jan/2024:10:30:29 +0800] "GET&nbsp;/nonexistent HTTP/1.1" 404 123 "http://example.com" "Safari/14.0"
192.168.1.2 - - [15/Jan/2024:10:30:30 +0800] "GET&nbsp;/api/data HTTP/1.1" 200 3456 "http://example.com" "Mozilla/5.0"
EOF

echo "🌐 Web服务器日志:"
cat web_server.log
echo "========================================"

# 高级日志分析
awk '
{
&nbsp; &nbsp; # 使用match提取日志字段
&nbsp; &nbsp; if (match($0, /^([0-9.]+) .* \[(.*)\] "(.*)" ([0-9]+) ([0-9]+) "(.*)" "(.*)"/, arr)) {
&nbsp; &nbsp; &nbsp; &nbsp; ip = arr[1]
&nbsp; &nbsp; &nbsp; &nbsp; timestamp = arr[2]
&nbsp; &nbsp; &nbsp; &nbsp; request = arr[3]
&nbsp; &nbsp; &nbsp; &nbsp; status = arr[4]
&nbsp; &nbsp; &nbsp; &nbsp; bytes = arr[5]
&nbsp; &nbsp; &nbsp; &nbsp; referer = arr[6]
&nbsp; &nbsp; &nbsp; &nbsp; user_agent = arr[7]

&nbsp; &nbsp; &nbsp; &nbsp; # 进一步解析请求
&nbsp; &nbsp; &nbsp; &nbsp; if (match(request, /^([A-Z]+) (.*) HTTP/, req_arr)) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; method = req_arr[1]
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; path = req_arr[2]

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # 统计信息
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ip_count[ip]++
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; status_count[status]++
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; method_count[method]++
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; total_bytes += bytes

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # 路径分析
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (match(path, "^/[^/?]*", path_arr)) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; endpoint = path_arr[0]
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; endpoint_count[endpoint]++
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; endpoint_bytes[endpoint] += bytes
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; }
}
END {
&nbsp; &nbsp; print "📊 访问统计报告"
&nbsp; &nbsp; print "================"

&nbsp; &nbsp; # IP统计
&nbsp; &nbsp; print "\n🌐 客户端IP统计:"
&nbsp; &nbsp; for (ip in ip_count) {
&nbsp; &nbsp; &nbsp; &nbsp; printf "%-15s: %d次访问\n", ip, ip_count[ip]
&nbsp; &nbsp; }

&nbsp; &nbsp; # 状态码统计
&nbsp; &nbsp; print "\n📋 HTTP状态码分布:"
&nbsp; &nbsp; for (status in status_count) {
&nbsp; &nbsp; &nbsp; &nbsp; printf "%-4s: %d次\n", status, status_count[status]
&nbsp; &nbsp; }

&nbsp; &nbsp; # 方法统计
&nbsp; &nbsp; print "\n🛠️ &nbsp;请求方法统计:"
&nbsp; &nbsp; for (method in method_count) {
&nbsp; &nbsp; &nbsp; &nbsp; printf "%-6s: %d次\n", method, method_count[method]
&nbsp; &nbsp; }

&nbsp; &nbsp; # 端点统计
&nbsp; &nbsp; print "\n📍 热门端点:"
&nbsp; &nbsp; for (endpoint in endpoint_count) {
&nbsp; &nbsp; &nbsp; &nbsp; if (endpoint_count[endpoint] > 1) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; avg_size = endpoint_bytes[endpoint] / endpoint_count[endpoint]
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; printf "%-12s: %d次访问, 平均%.0f字节\n",
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;endpoint, endpoint_count[endpoint], avg_size
&nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; }

&nbsp; &nbsp; # 总体统计
&nbsp; &nbsp; print "\n📈 总体统计:"
&nbsp; &nbsp; printf "总请求数: %d\n", NR
&nbsp; &nbsp; printf "总流量: %.1fKB\n", total_bytes / 1024
&nbsp; &nbsp; printf "平均请求大小: %.0f字节\n", total_bytes / NR
}' web_server.log

# 清理
rm web_server.log

5.2 配置文件处理

#!/bin/bash
# awk-config-processing.sh

echo"=== AWK 配置文件处理实战 ==="

# 创建复杂的配置文件
cat > app_config.conf <<&nbsp;'EOF'
# Database Configuration
db.host = mysql.example.com
db.port = 3306
db.name = myapp_db
db.user = admin
db.password = secret123

# Server Settings
server.host = 0.0.0.0
server.port = 8080
server.timeout = 30
server.ssl.enabled =&nbsp;true
server.ssl.cert = /path/to/cert.pem

# Logging
log.level = INFO
log.file = /var/log/app.log
log.max_size = 100MB

# Feature Flags
features.api.enabled =&nbsp;true
features.ui.enabled =&nbsp;false
features.debug.mode =&nbsp;false
EOF

echo"⚙️ &nbsp;配置文件内容:"
cat app_config.conf
echo"========================================"

# 高级配置文件处理
awk&nbsp;'
function parse_section(line, &nbsp; &nbsp;parts) {
&nbsp; &nbsp; if (match(line, /^# ([A-Za-z ]+)$/, arr)) {
&nbsp; &nbsp; &nbsp; &nbsp; current_section = arr[1]
&nbsp; &nbsp; &nbsp; &nbsp; sections[current_section] = ""
&nbsp; &nbsp; &nbsp; &nbsp; return 1
&nbsp; &nbsp; }
&nbsp; &nbsp; return 0
}

function parse_setting(line, &nbsp; &nbsp;key, value, parts) {
&nbsp; &nbsp; if (match(line, /^([a-zA-Z0-9._]+) *= *(.*)$/, arr)) {
&nbsp; &nbsp; &nbsp; &nbsp; key = arr[1]
&nbsp; &nbsp; &nbsp; &nbsp; value = arr[2]

&nbsp; &nbsp; &nbsp; &nbsp; # 移除行尾注释
&nbsp; &nbsp; &nbsp; &nbsp; gsub(/#.*$/, "", value)
&nbsp; &nbsp; &nbsp; &nbsp; gsub(/^ *| *$/, "", value) &nbsp;# 去除首尾空格

&nbsp; &nbsp; &nbsp; &nbsp; # 存储配置
&nbsp; &nbsp; &nbsp; &nbsp; settings[key] = value
&nbsp; &nbsp; &nbsp; &nbsp; setting_sections[key] = current_section

&nbsp; &nbsp; &nbsp; &nbsp; # 按section分组
&nbsp; &nbsp; &nbsp; &nbsp; section_settings[current_section][key] = value

&nbsp; &nbsp; &nbsp; &nbsp; return 1
&nbsp; &nbsp; }
&nbsp; &nbsp; return 0
}

{
&nbsp; &nbsp; # 跳过空行
&nbsp; &nbsp; if ($0 ~ /^[[:space:]]*$/) next

&nbsp; &nbsp; # 解析section
&nbsp; &nbsp; if (!parse_section($0)) {
&nbsp; &nbsp; &nbsp; &nbsp; # 解析配置项
&nbsp; &nbsp; &nbsp; &nbsp; if (!parse_setting($0)) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print "无法解析行:", NR ": " $0 > "/dev/stderr"
&nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; }
}

END {
&nbsp; &nbsp; print "📋 配置分析报告"
&nbsp; &nbsp; print "================"

&nbsp; &nbsp; # 按section输出配置
&nbsp; &nbsp; print "\n📁 配置分组:"
&nbsp; &nbsp; for (section in sections) {
&nbsp; &nbsp; &nbsp; &nbsp; print "\n" section ":"
&nbsp; &nbsp; &nbsp; &nbsp; print "---------"
&nbsp; &nbsp; &nbsp; &nbsp; for (key in section_settings[section]) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; value = section_settings[section][key]
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; printf "%-20s = %s\n", key, value
&nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; }

&nbsp; &nbsp; # 统计信息
&nbsp; &nbsp; print "\n📊 配置统计:"
&nbsp; &nbsp; printf "总配置项数: %d\n", length(settings)
&nbsp; &nbsp; printf "配置段落数: %d\n", length(sections)

&nbsp; &nbsp; # 敏感信息检查
&nbsp; &nbsp; print "\n🔒 敏感信息检查:"
&nbsp; &nbsp; sensitive_patterns["password"] = "密码"
&nbsp; &nbsp; sensitive_patterns["secret"] = "密钥"
&nbsp; &nbsp; sensitive_patterns["cert"] = "证书"

&nbsp; &nbsp; for (key in settings) {
&nbsp; &nbsp; &nbsp; &nbsp; for (pattern in sensitive_patterns) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (index(tolower(key), pattern) > 0) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; printf "

免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:运维星火燎原 刘军军 刘军军《Linux AWK 高级用法深度解析》

评论:0   参与:  0