本文目录导读:

我来介绍几种在Shell脚本中统计日志IP访问量的方法:
基本统计方法
使用awk和sort组合
#!/bin/bash
# 统计所有IP的访问次数
awk '{print $1}' access.log | sort | uniq -c | sort -rn
# 输出格式: 访问次数 IP地址
统计访问最多的前N个IP
#!/bin/bash
# 显示访问量前10的IP
awk '{print $1}' access.log | sort | uniq -c | sort -rn | head -10
完整的统计脚本
#!/bin/bash
# 日志文件路径
LOG_FILE="/var/log/nginx/access.log"
TOP_N=10
echo "========== IP访问统计 =========="
echo "总访问IP数:"
awk '{print $1}' $LOG_FILE | sort -u | wc -l
echo ""
echo "访问量前${TOP_N}的IP:"
echo "访问次数 IP地址"
echo "------------------------"
awk '{print $1}' $LOG_FILE | sort | uniq -c | sort -rn | head -${TOP_N}
echo ""
echo "各IP访问详情:"
awk '{ips[$1]++} END {for (ip in ips) printf "%-15s %d次\n", ip, ips[ip]}' $LOG_FILE | sort -k2 -rn
增强版统计脚本
#!/bin/bash
# 配置文件路径
LOG_FILE="${1:-/var/log/nginx/access.log}"
TOP_N="${2:-10}"
# 检查日志文件
if [ ! -f "$LOG_FILE" ]; then
echo "错误:日志文件 $LOG_FILE 不存在"
exit 1
fi
echo "========================================"
echo " 日志文件: $LOG_FILE"
echo " 统计时间: $(date '+%Y-%m-%d %H:%M:%S')"
echo "========================================"
# 1. 统计总访问量
total=$(wc -l < "$LOG_FILE")
unique_ips=$(awk '{print $1}' "$LOG_FILE" | sort -u | wc -l)
echo "总请求数: $total"
echo "独立IP数: $unique_ips"
echo ""
# 2. 按IP统计访问量
echo "=== IP访问排名 Top ${TOP_N} ==="
echo "排名 访问次数 IP地址"
echo "------------------------"
awk '{
ips[$1]++
} END {
for (ip in ips) {
printf "%s\t%d\n", ip, ips[ip]
}
}' "$LOG_FILE" | sort -k2 -rn | head -${TOP_N} | awk '{
printf "%3d %-10d %s\n", NR, $2, $1
}'
echo ""
# 3. 统计访问量分布
echo "=== 访问量分布 ==="
awk '{
ips[$1]++
} END {
for (ip in ips) {
count = ips[ip]
if (count == 1) level1++
else if (count <= 5) level2++
else if (count <= 10) level3++
else if (count <= 50) level4++
else level5++
}
printf "访问1次: %d个IP\n", level1
printf "访问2-5次: %d个IP\n", level2
printf "访问6-10次: %d个IP\n", level3
printf "访问11-50次: %d个IP\n", level4
printf "访问50次+: %d个IP\n", level5
}' "$LOG_FILE"
# 4. 统计恶意IP(访问量异常高的IP)
echo ""
echo "=== 疑似恶意IP(访问量>500次) ==="
awk '{
ips[$1]++
} END {
for (ip in ips) {
if (ips[ip] > 500) {
printf "%-15s %d次\n", ip, ips[ip]
}
}
}' "$LOG_FILE" | sort -k2 -rn
针对不同日志格式的统计
Apache日志格式
# Apache combined格式(IP在第一列)
awk '{print $1}' access.log | sort | uniq -c | sort -rn
Nginx日志格式
# Nginx默认格式(IP在第一列)
awk '{print $1}' access.log | sort | uniq -c | sort -rn
自定义日志格式
# 如果IP在其他位置,需要调整awk的列号
# IP在第7列
awk '{print $7}' access.log | sort | uniq -c | sort -rn
按时间段统计
#!/bin/bash
LOG_FILE="/var/log/nginx/access.log"
# 统计今天的IP访问量
echo "今天各IP访问量:"
awk -v date=$(date '+%d/%b/%Y') '$4 ~ date {print $1}' $LOG_FILE | sort | uniq -c | sort -rn
# 统计最近一小时的IP访问量
echo ""
echo "最近一小时各IP访问量:"
awk -v time=$(date -d '1 hour ago' '+%H:%M:%S') '{
split($4, dt, "/");
split(dt[3], t, ":");
hour = t[2]":"t[3]":"t[4];
if (hour >= time) print $1
}' $LOG_FILE | sort | uniq -c | sort -rn
高级统计:IP地理信息
#!/bin/bash
# 需要安装 geoip-bin 包
# apt-get install geoip-bin
LOG_FILE="/var/log/nginx/access.log"
echo "=== IP地理位置分布 ==="
awk '{print $1}' $LOG_FILE | sort -u | while read ip; do
country=$(geoiplookup $ip 2>/dev/null | awk -F: '{print $2}')
echo "$country $ip"
done | sort | uniq -c | sort -rn
使用示例
# 1. 单行命令快速统计
awk '{print $1}' access.log | sort | uniq -c | sort -rn | head -10
# 2. 保存脚本并执行
chmod +x ip_stats.sh
./ip_stats.sh /path/to/access.log
# 3. 实时监控
tail -f access.log | awk '{ips[$1]++} {system("clear"); for(ip in ips) printf "%-15s %d\n", ip, ips[ip]}'
注意事项
- 日志格式确认:确保awk中使用的列号与日志格式匹配
- 大文件处理:对于大日志文件,建议使用
sort -S指定内存使用 - 性能优化:
# 使用更高效的命令 awk '{count[$1]++} END{for(ip in count) print count[ip], ip}' access.log | sort -rn - 排除特定IP:
awk '{if($1 != "127.0.0.1") ips[$1]++} END{for(ip in ips) print ips[ip], ip}' access.log
这些脚本可以帮你快速分析IP访问情况,适合日常运维和日志分析使用。