Linux-sed-date.png

I. 主理人序

II. 命令行工具介绍

需要使用到两个命令,sed命令、date命令;前者是优秀的文本处理(命令行)工具,后者可打印不同格式的时间戳;

sed命令介绍

选定行的范围:,(英语逗号)**

所有在模板test和check所确定的范围内的行都被打印:

sed -n '/test/,/check/p' file

sed命令_Linux sed 命令用法详解:功能强大的流式文本编辑器.pdf
via sed命令

date命令介绍

date +%Y:%H:%M

date命令是显示或设置系统时间与日期。

很多shell脚本里面需要打印不同格式的时间或日期,以及要根据时间和日期执行操作。延时通常用于脚本执行过程中提供一段等待的时间。日期可以以多种格式去打印,也可以使用命令设置固定的格式。在类UNIX系统中,日期被存储为一个整数,其大小为自世界标准时间(UTC)1970年1月1日0时0分0秒起流逝的秒数。

语法

date(选项)(参数)

选项

-d<字符串>:显示字符串所指的日期与时间。字符串前后必须加上双引号;
-s<字符串>:根据字符串来设置日期与时间。字符串前后必须加上双引号;
-u:显示GMT;
--help:在线帮助;
--version:显示版本信息。

参数 <+时间日期格式>:指定显示时使用的日期时间格式。

%H 小时,24小时制(00~23)
%I 小时,12小时制(01~12)
%k 小时,24小时制(0~23)
%l 小时,12小时制(1~12)
%M 分钟(00~59)
%p 显示出AM或PM
%r 显示时间,12小时制(hh:mm:ss %p)
%s 从1970年1月1日00:00:00到目前经历的秒数
%S 显示秒(00~59)
%T 显示时间,24小时制(hh:mm:ss)
%X 显示时间的格式(%H:%M:%S)
%Z 显示时区,日期域(CST)
%a 星期的简称(Sun~Sat)
%A 星期的全称(Sunday~Saturday)
%h,%b 月的简称(Jan~Dec)
%B 月的全称(January~December)
%c 日期和时间(Tue Nov 20 14:12:58 2012)
%d 一个月的第几天(01~31)
%x,%D 日期(mm/dd/yy)
%j 一年的第几天(001~366)
%m 月份(01~12)
%w 一个星期的第几天(0代表星期天)
%W 一年的第几个星期(00~53,星期一为第一天)
%y 年的最后两个数字(1999则是99)

实例
此时的时刻:

date +%H:%M:%S
12:07:45

5分钟前的时刻:

date -d "-"5"min" +%H:%M:%S
12:03:08

注意,5分钟前为减操作,如想知道5分钟后的时刻可使用加操作,即把加号+变成减号即可;减号后面的min代表分钟,可代替参数有daymonthyear

date命令_Linux date 命令用法详解:显示或设置系统时间与日期.pdf
via date命令

III. 截取日志(实例)

在刚刚的命令行工具介绍中我们已经知道了seddate两个命令行工具的用法,大家可以更深入的了解以便做更多好玩的事情;

sed -n '/start/,/end/p' file

使用该命令可以从文本内的第一个包含start内容的部分截取直到end为止;

现在找出你的网站访问日志(nginx),他们的内容一般如下(以下非真实用户IP,已做后期处理),该日志文件位置为:/home/wwwlogs/limbopro.com/access.log

...
219.25.120.201 - - [06/Apr/2021:09:20:10 +0800] "GET //feed HTTP/1.1" 200 27401 "https://limbopro.com//feed" "FreshRSS/1.18.0 (Linux; https://freshrss.org)"
23.116.47.198 - - [06/Apr/2021:09:20:13 +0800] "GET /archives/10713.html HTTP/1.1" 200 25543 "https://www.google.com/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36"
128.162.142.226 - - [06/Apr/2021:09:20:14 +0800] "GET /Adblock4limbo.list HTTP/1.1" 200 3068 "-" "Go-http-client/1.1"
223.242.140.34 - - [06/Apr/2021:09:20:25 +0800] "GET /archives/3629.html HTTP/1.1" 200 35789 "https://www.google.co.jp/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.3 Safari/605.1.15"
252.157.251.20 - - [06/Apr/2021:09:20:27 +0800] "GET /865.html HTTP/1.1" 200 37710 "-" "Mozilla/5.0 (Linux; U; Android 10; zh-Hans-CN; PCT-AL10 Build/HUAWEIPCT-AL10) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.108 Quark/4.8.3.173 Mobile Safari/537.36"
22.247.181.29 - - [06/Apr/2021:09:20:33 +0800] "GET /feed/ HTTP/1.1" 200 27402 "https://limbopro.com/" "Mozilla/5.0 (compatible; inoreader.com; 27 subscribers)"
203.116.47.198 - - [06/Apr/2021:09:20:35 +0800] "GET /btsearch.html HTTP/1.1" 200 5043 "https://limbopro.com/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36"
203.157.251.10 - - [06/Apr/2021:09:20:39 +0800] "GET /category/NSFW/ HTTP/1.1" 200 15891 "-" "Mozilla/5.0 (Linux; U; Android 10; zh-Hans-CN; PCT-AL10 Build/HUAWEIPCT-AL10) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.108 Quark/4.8.3.173 Mobile Safari/537.36"
203.157.251.21 - - [06/Apr/2021:09:20:46 +0800] "HEAD / HTTP/1.1" 200 0 "-" "curl/7.68.0"
203.187.252.21 - - [06/Apr/2021:09:21:01 +0800] "GET /feed HTTP/1.1" 200 27401 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3837.0 Safari/537.36 Edg/77.0.211.2"
34.41.212.26 - - [06/Apr/2021:09:21:02 +0800] "HEAD / HTTP/1.1" 200 0 "-" "curl/7.68.0"
35.10.14.41 - - [06/Apr/2021:09:21:05 +0800] "GET /Adblock4limbo.list HTTP/1.1" 200 3068 "-" "Quantumult%20X/1.0.20 (iPhone12,3; iOS 14.4.2)"
35.40.214.66 - - [06/Apr/2021:09:21:05 +0800] "GET /Adblock4limbo.conf HTTP/1.1" 200 12292 "-" "Quantumult%20X/1.0.20 (iPhone12,3; iOS 14.4.2)"
203.182.140.34 - - [06/Apr/2021:09:21:11 +0800] "GET /archives/11773.html HTTP/1.1" 200 29060 "https://limbopro.com/archives/3629.html" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.3 Safari/605.1.15"
242.57.200.186 - - [06/Apr/2021:09:21:14 +0800] "GET /Adblock4limbo.list HTTP/1.1" 200 3068 "-" "Quantumult%20X/1.0.20 (iPad11,1; iOS 14.4.1)"
213.157.251.2 - - [06/Apr/2021:09:21:15 +0800] "GET /archives/15154.html?_pjax=%23content HTTP/1.1" 200 23037 "https://limbopro.com/category/NSFW/" "Mozilla/5.0 (Linux; U; Android 10; zh-Hans-CN; PCT-AL10 Build/HUAWEIPCT-AL10) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.108 Quark/4.8.3.173 Mobile Safari/537.36"
229.57.220.156 - - [06/Apr/2021:09:21:19 +0800] "GET /Adblock4limbo.conf HTTP/1.1" 200 12292 "-" "Quantumult%20X/1.0.20 (iPad11,1; iOS 14.4.1)"
145.176.190.152 - - [06/Apr/2021:09:21:25 +0800] "GET /archives/clashA.html HTTP/1.1" 200 25177 "https://www.google.com/" "Mozilla/5.0 (Linux; Android 10; ONEPLUS A6000) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.105 Mobile Safari/537.36"
223.147.211.21 - - [06/Apr/2021:09:21:34 +0800] "GET /category/by-nc-sa.png HTTP/1.1" 404 1707 "https://limbopro.com/category/NSFW/" "Mozilla/5.0 (Linux; U; Android 10; zh-Hans-CN; PCT-AL10 Build/HUAWEIPCT-AL10) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.108 Quark/4.8.3.173 Mobile Safari/537.36"
223.57.111.134 - - [06/Apr/2021:09:21:42 +0800] "GET /archives/15154.html?_pjax=%23content HTTP/1.1" 200 23037 "https://limbopro.com/category/NSFW/" "Mozilla/5.0 (Linux; U; Android 10; zh-Hans-CN; PCT-AL10 Build/HUAWEIPCT-AL10) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.108 Quark/4.8.3.173 Mobile Safari/537.36"
...

我们要从 2021:09:20:10 这个时刻开始提取,直至2021:09:20:39 我们要怎么做呢?

sed -n '/2021:09:20:10/,/2021:09:20:39/p' /home/wwwlogs/limbopro.com/access.log

以上命令直接将结果打印显示在终端,如要将结果导入到一个临时文本可进行如下操作:

sed -n '/2021:09:20:10/,/2021:09:20:39/p' /home/wwwlogs/limbopro.com/access.log > /home/wwwlogs/limbopro.com/temp.log

文件位置可根据需要自行拟定;关于终端命令的结果输出/输入的使用方法可参考Shell 输入/输出重定向Shell 输入_输出重定向.pdf

完美!

IV. 真实应用场景(思路及实例)

本博客在2019-2020年期间为了做防御挨了不少打(友情压测),由此不得不制作一个脚本,截取过去一分钟内产生的访问日志,然后利用其它命令行工具进行分析,计算单个IP发起get/post/head请求的访问次数,如异常则将该IP单独提取到一个文本;

就这一使用场景我们制作了以下脚本:

#!/bin/bash
## access.log.cut.sh
Interval=1;
Then="`date -d "-"$Interval"min" +%Y:%H:%M`";
Now="`date +%Y:%H:%M`";
#提取近1分钟日志

PathtoLog=/home/wwwlogs/limbopro.com/access.log; 
#原始日志位置(根据实际情况修改)
PathtoTempLog=/home/wwwlogs/limbopro.com/temp.log 
#提取至临时日志位置(根据实际情况修改)
sed -n  '/'$Then'/','/'$Now'/p' $PathtoLog > $PathtoTempLog;
#使用 sed 命令进行日志提取

这些命令都怎么来的?都是各种单一命令的组合;

$ date +%Y:%H:%M
2021:12:34

刚好满足访问日志的格式;

145.176.190.152 - - [06/Apr/2021:09:21:25 +0800] "GET /archives/clashA.html HTTP/1.1" 200 25177 "https://www.google.com/" "Mozilla/5.0 (Linux; Android 10; ONEPLUS A6000) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.105 Mobile Safari/537.36"

为什么不要参数%S(即显示秒),date +%Y:%H:%M%S,其实这样会造成不小的麻烦,因为你不能保证 12:34:23 有人访问(因为这个范围太小了,就像关键字越多,搜索结果越少越精准一样);如果是 12:34 则大不一样,一分钟内有访客访问的概率肯定是要大于一分钟内的某一秒要高得多得多;

Get 到了吗?

最后修改:2021 年 05 月 25 日 09 : 42 AM