Linux脚本练习之script080-nginx日志分析之IP统计

这篇博客介绍了如何使用Shell脚本来从nginx日志中提取特定日期(如2020年4月23日)的访问IP,并按访问次数降序排序。提供了三种不同的Shell脚本实现方式,分别是利用grep、awk、sort和uniq-c命令的组合,以及使用bash关联数组和awk的内建数组。这些脚本能够有效地统计和排序日志中的IP访问频率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

script080

题目

注:题目来源于 SHELL23 nginx日志分析1-IP统计

假设 nginx 的日志我们存储在 nowcoder.txt 里,格式如下:

192.168.1.20 - - [21/Apr/2020:14:27:49 +0800] "GET /1/index.php HTTP/1.1" 404 490 "-" "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:45.0) Gecko/20100101 Firefox/45.0"
192.168.1.21 - - [21/Apr/2020:15:27:49 +0800] "GET /2/index.php HTTP/1.1" 404 490 "-" "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:45.0) Gecko/20100101 Firefox/45.0"
192.168.1.22 - - [21/Apr/2020:21:27:49 +0800] "GET /3/index.php HTTP/1.1" 404 490 "-" "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:45.0) Gecko/20100101 Firefox/45.0"
192.168.1.23 - - [21/Apr/2020:22:27:49 +0800] "GET /1/index.php HTTP/1.1" 404 490 "-" "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:45.0) Gecko/20100101 Firefox/45.0"
192.168.1.24 - - [22/Apr/2020:15:27:49 +0800] "GET /2/index.php HTTP/1.1" 404 490 "-" "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:45.0) Gecko/20100101 Firefox/45.0"
192.168.1.25 - - [22/Apr/2020:15:26:49 +0800] "GET /3/index.php HTTP/1.1" 404 490 "-" "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:45.0) Gecko/20100101 Firefox/45.0"
192.168.1.20 - - [23/Apr/2020:08:27:49 +0800] "GET /1/index.php HTTP/1.1" 404 490 "-" "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:45.0) Gecko/20100101 Firefox/45.0"
192.168.1.21 - - [23/Apr/2020:09:20:49 +0800] "GET /1/index.php HTTP/1.1" 404 490 "-" "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:45.0) Gecko/20100101 Firefox/45.0"
192.168.1.22 - - [23/Apr/2020:10:27:49 +0800] "GET /1/index.php HTTP/1.1" 404 490 "-" "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:45.0) Gecko/20100101 Firefox/45.0"
192.168.1.22 - - [23/Apr/2020:10:27:49 +0800] "GET /1/index.php HTTP/1.1" 404 490 "-" "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:45.0) Gecko/20100101 Firefox/45.0"
192.168.1.20 - - [23/Apr/2020:14:27:49 +0800] "GET /1/index.php HTTP/1.1" 404 490 "-" "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:45.0) Gecko/20100101 Firefox/45.0"
192.168.1.21 - - [23/Apr/2020:15:27:49 +0800] "GET /2/index.php HTTP/1.1" 404 490 "-" "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:45.0) Gecko/20100101 Firefox/45.0"
192.168.1.22 - - [23/Apr/2020:15:27:49 +0800] "GET /3/index.php HTTP/1.1" 404 490 "-" "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:45.0) Gecko/20100101 Firefox/45.0"
192.168.1.25 - - [23/Apr/2020:16:27:49 +0800] "GET /1/index.php HTTP/1.1" 404 490 "-" "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:45.0) Gecko/20100101 Firefox/45.0"
192.168.1.24 - - [23/Apr/2020:20:27:49 +0800] "GET /2/index.php HTTP/1.1" 404 490 "-" "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:45.0) Gecko/20100101 Firefox/45.0"
192.168.1.25 - - [23/Apr/2020:20:27:49 +0800] "GET /3/index.php HTTP/1.1" 404 490 "-" "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:45.0) Gecko/20100101 Firefox/45.0"
192.168.1.20 - - [23/Apr/2020:20:27:49 +0800] "GET /1/index.php HTTP/1.1" 404 490 "-" "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:45.0) Gecko/20100101 Firefox/45.0"
192.168.1.21 - - [23/Apr/2020:20:27:49 +0800] "GET /1/index.php HTTP/1.1" 404 490 "-" "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:45.0) Gecko/20100101 Firefox/45.0"
192.168.1.22 - - [23/Apr/2020:20:27:49 +0800] "GET /1/index.php HTTP/1.1" 404 490 "-" "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:45.0) Gecko/20100101 Firefox/45.0"
192.168.1.22 - - [23/Apr/2020:15:27:49 +0800] "GET /1/index.php HTTP/1.1" 404 490 "-" "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:45.0) Gecko/20100101 Firefox/45.0"
192.168.1.21 - - [23/Apr/2020:20:27:49 +0800] "GET /1/index.php HTTP/1.1" 404 490 "-" "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:45.0) Gecko/20100101 Firefox/45.0"

现在需要你统计出2020年4月23号的访问 ip 次数,并且按照次数降序排序。你的脚本应该输出:

5 192.168.1.22
4 192.168.1.21
3 192.168.1.20
2 192.168.1.25
1 192.168.1.24

脚本一

首先使用 grep 命令检索到2020年4月23号的记录行;接着使用 awk 命令打印第一个字段域,即 IP 地址列;接着通过 sort 命令排序;再通过 uniq -c 命令对排序后的结果进行去重统计出现次数;再通过 sort -nr 命令对每个 IP 地址的出现次数逆序排列;最后通过 sed 命令去重行首多余的空格。

grep "23/Apr/2020" nowcoder.txt | awk '{print $1}' | sort | uniq -c | sort -nr | sed 's/[ \t]*//'

脚本二

通过 shell 编程实现,首先使用 declare 命令声明一个关联数组;再循环读取文件中的每一行的 IP 地址,将其出现次数记录在关联数组中;由于要对最终结果降序排列,所以不仅要输出关联数组的键名和对应的键值,还得把它们拼接成一个字符串通过管道符传递给 sort 命令排序。

#!/bin/bash

# 声明一个关联数组
declare -A map

# 循环读取文件中的每一行,提取每行的 IP 地址,以 IP 地址作为关联数组的键名,对应的出现次数作为键值
while read line; do
  # 如果不是2020年4月23号的记录则跳过
  if ! echo "${line}"| grep "23/Apr/2020" > /dev/null; then
    continue 
  fi
  # 提取文本行的 IP 地址
  ip=$(echo "${line}" | awk '{print $1}')
  # 把出现次数记录在关联数组中
  map["${ip}"]=$(( map["${ip}"] + 1 ))
done < nowcoder.txt  

# 把IP地址和出现次数记录在这个变量上,为了能排序
result=""
# 循环输出关联数组中的所有元素
for k in ${!map[@]} ; do
  if [ -z "${result}" ]; then
      result="${map[$k]} ${k}"
  else
      result="${result}\n${map[$k]} ${k}"
  fi
done
# 最终对结果进行排序
echo -e "${result}" | sort -nr

脚本三

跟脚本二的原理一样,只是通过 awk 命令来完成,都是通过关联数组来完成的。

awk '/23\/Apr\/2020/{map[$1]++} END{for(k in map) print map[k],k}' nowcoder.txt | sort -nr
<think>嗯,用户之前问过关于“欧邦图系统”的代码,但那个系统可能不存在或者名称有误。现在他们转向询问Ubuntu系统操作命令,这说明用户可能需要学习Linux系统的基本操作,特别是Ubuntu的使用。 首先,我需要确认用户的使用场景。可能是刚接触Ubuntu的新手,想要学习基本的命令行操作。用户可能是学生、开发人员或者系统管理员,需要掌握日常管理任务,比如文件操作、软件安装、系统监控等。 接下来,用户的需求可能不仅仅是记住命令,而是理解每个命令的作用和使用场景。比如,他们可能想知道如何查找文件、管理进程、处理权限问题,或者配置网络。此外,用户可能对包管理系统(如apt)和脚本编写感兴趣,以便自动化任务。 需要确保回答的结构清晰,分门别类,便于用户逐步学习。同时,加入一些实用技巧和注意事项,比如使用sudo时的风险,权限管理的重要性,以及如何获取帮助文档,这些都能帮助用户避免常见错误。 还要考虑用户可能的深层需求,比如他们是否在搭建服务器、进行软件开发,或者只是日常使用。不同的使用场景可能需要不同的命令组合。例如,开发人员可能需要gcc和版本控制工具,而系统管理员可能更关注日志分析和服务管理。 最后,确保回答准确,命令语法正确,并提供示例,这样用户可以跟着练习。同时提醒用户谨慎执行需要权限的命令,避免系统损坏。可能还需要推荐进一步的学习资源,如手册页、在线教程或社区支持,帮助用户深入学习。</think>以下是 **Ubuntu 系统常用操作命令**的分类整理,包含基础文件操作、系统管理及实用技巧: --- ### 一、文件与目录操作 | 命令 | 功能 | 示例 | |------|------|------| | `ls` | 列出目录内容 | `ls -l`(详细列表)<br> `ls -a`(显示隐藏文件) | | `cd` | 切换目录 | `cd /var/www`(绝对路径)<br> `cd ..`(返回上级) | | `pwd` | 显示当前路径 | `pwd` → 输出 `/home/user` | | `cp` | 复制文件/目录 | `cp file.txt backup/`<br> `cp -r dir1/ dir2/`(递归复制目录) | | `mv` | 移动/重命名 | `mv old.txt new.txt`(重命名)<br> `mv file.txt ~/Documents/`(移动) | | `rm` | 删除文件/目录 | `rm file.txt`<br> `rm -rf dir/`(强制递归删除)⚠️慎用 | | `find` | 文件搜索 | `find / -name "*.log"`(全盘搜索.log文件) | --- ### 二、文本处理 | 命令 | 功能 | 示例 | |------|------|------| | `cat` | 显示文件内容 | `cat file.txt` | | `grep` | 文本搜索 | `grep "error" log.txt`(查找含"error"的行) | | `nano`/`vim` | 文本编辑 | `nano file.txt`(简单编辑)<br> `vim file.txt`(高级编辑) | | `chmod` | 修改权限 | `chmod 755 script.sh`(rwxr-xr-x) | | `chown` | 修改所有者 | `chown user:group file.txt` | --- ### 三、系统管理 | 命令 | 功能 | 示例 | |------|------|------| | `sudo` | 提权执行 | `sudo apt update`(以root权限运行) | | `apt` | 包管理 | `sudo apt install nginx`(安装软件)<br> `sudo apt remove python3`(卸载) | | `systemctl` | 服务管理 | `sudo systemctl start apache2`(启动服务)<br> `sudo systemctl enable docker`(开机自启) | | `top`/`htop` | 进程监控 | `top`(实时资源占用)<br> `htop`(增强版) | | `df`/`du` | 磁盘空间 | `df -h`(查看磁盘剩余)<br> `du -sh dir/`(统计目录大小) | --- ### 四、网络相关 | 命令 | 功能 | 示例 | |------|------|------| | `ping` | 网络连通性 | `ping google.com` | | `ifconfig`/`ip` | 网络配置 | `ip addr show`(显示IP地址) | | `ssh` | 远程连接 | `ssh user@192.168.1.100` | | `scp` | 安全传输 | `scp file.txt user@remote:/path/`(上传) | | `wget`/`curl` | 下载工具 | `wget https://example.com/file.zip` | --- ### 五、实用技巧 1. **历史命令**:按 `Ctrl+R` 搜索历史命令 2. **通配符**:`*.txt` 匹配所有文本文件,`?` 匹配单个字符 3. **管道符**:`ls -l \| grep "2023"`(筛选2023年修改的文件) 4. **后台运行**:`nohup command &`(退出终端仍运行) 5. **帮助文档**:`man ls`(查看手册)或 `命令 --help` --- ### ⚠️ 注意事项 - 使用 `sudo` 前确认命令安全性 - 删除命令(`rm`、`dd`)需谨慎 - 重要文件操作前建议备份 如果需要更具体的场景(如**Shell脚本编写**或**服务器配置**),请补充说明! 😊
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值