本文目录导读:

我来介绍几种从日志中提取关键字段的Shell脚本方法:
使用grep和awk提取字段
基本格式提取
#!/bin/bash
# 假设日志格式: [2024-01-15 10:30:45] ERROR: 用户ID=12345 操作=登录 IP=192.168.1.1
# 提取所有ERROR级别的日志
grep "ERROR" app.log
# 提取特定字段(用户ID)
grep "ERROR" app.log | awk '{print $4}'
# 使用awk按分隔符提取
awk -F'=' '{print $2}' app.log | awk '{print $1}'
使用sed进行复杂提取
#!/bin/bash # 提取IP地址 sed -n 's/.*IP=\([0-9.]*\).*/\1/p' app.log # 提取时间戳 sed -n 's/\[\(.*\)\].*/\1/p' app.log # 提取特定模式之间的内容 sed -n 's/.*用户ID=\([0-9]*\).*/\1/p' app.log
完整的日志解析脚本
#!/bin/bash
# 日志分析脚本
LOG_FILE="application.log"
# 提取错误日志并格式化
echo "===== 错误日志分析 ====="
grep "ERROR" "$LOG_FILE" | while read line; do
# 提取时间
timestamp=$(echo "$line" | grep -oP '\[\K[^\]]+')
# 提取用户ID
user_id=$(echo "$line" | grep -oP '用户ID=\K[0-9]+')
# 提取操作类型
action=$(echo "$line" | grep -oP '操作=\K[^ ]+')
# 提取IP
ip=$(echo "$line" | grep -oP 'IP=\K[0-9.]+')
echo "时间: $timestamp | 用户: $user_id | 操作: $action | IP: $ip"
done
# 统计各操作次数
echo -e "\n===== 操作统计 ====="
grep -oP '操作=\K[^ ]+' "$LOG_FILE" | sort | uniq -c | sort -rn
提取结构化日志(JSON格式)
#!/bin/bash
# 处理JSON格式日志
# 示例: {"timestamp":"2024-01-15","level":"ERROR","user":"12345","action":"login","ip":"192.168.1.1"}
cat app.log | while read line; do
# 提取JSON字段
level=$(echo "$line" | python3 -c "import sys,json; print(json.load(sys.stdin)['level'])" 2>/dev/null)
user=$(echo "$line" | python3 -c "import sys,json; print(json.load(sys.stdin)['user'])" 2>/dev/null)
# 或者使用jq工具
level=$(echo "$line" | jq -r '.level')
user=$(echo "$line" | jq -r '.user')
if [ "$level" == "ERROR" ]; then
echo "Error by user: $user"
fi
done
高级提取示例
#!/bin/bash
# 综合提取脚本
extract_patterns() {
local log_file=$1
# 定义提取模式
patterns=(
"IP地址:IP=\K[0-9.]+"
"邮箱:[\w._%+-]+@[\w.-]+\.[A-Za-z]{2,}"
"订单号:ORD-\K[0-9]{8}"
"金额:\$\K[0-9.]+"
"电话号码:1[3-9]\K[0-9]{9}"
)
echo "===== 字段提取结果 ====="
# 遍历所有模式
for pattern in "${patterns[@]}"; do
field_name=$(echo "$pattern" | cut -d: -f1)
regex=$(echo "$pattern" | cut -d: -f2)
echo -e "\n提取 $field_name:"
grep -oP "$regex" "$log_file" | sort | uniq -c | sort -rn | head -10
done
# 统计提取总数
echo -e "\n===== 统计信息 ====="
total_lines=$(wc -l < "$log_file")
echo "总日志行数: $total_lines"
}
# 使用函数
extract_patterns "application.log"
实时日志监控提取
#!/bin/bash
# 实时监控并提取字段
tail -f application.log | while read line; do
# 检测并提取关键信息
if echo "$line" | grep -q "ERROR"; then
timestamp=$(echo "$line" | grep -oP '\[\K[^\]]+')
message=$(echo "$line" | grep -oP 'ERROR:\s*\K.*')
# 告警或记录
echo "[ALERT] $timestamp - $message" >> error_alerts.log
# 发送邮件或通知
# echo "Error detected: $message" | mail -s "Error Alert" admin@example.com
fi
done
常用的提取技巧
#!/bin/bash
# 1. 提取两个关键字之间的内容
grep -oP 'START\K.*?END' logfile
# 2. 提取固定列(使用cut)
cut -d' ' -f3-5 logfile
# 3. 多条件组合提取
awk '/ERROR/ && /user123/' logfile
# 4. 提取并格式化输出
awk '{
split($0, arr, " ")
for (i in arr) {
if (arr[i] ~ /^ERROR/) print "Level:", arr[i]
if (arr[i] ~ /^User:/) print "User:", substr(arr[i], 6)
}
}' logfile
使用建议
- 性能考虑:对于大文件,优先使用
awk和grep而不是循环 - 正则测试:使用
-o选项测试正则是否正确 - 数据验证:提取后增加验证步骤,确保数据完整性
- 错误处理:添加文件存在检查等错误处理
需要根据具体的日志格式调整提取方法和正则表达式。