如何提取文件中距今超30天的记录?脚本实现求助
解决方法:提取补丁日期早于指定日期/距今30天的行
原命令的问题
你的awk命令存在两个核心错误:
- 分割符选择错误:用
-F':'会把行按冒号拆分,导致$5根本不存在(每行最多只有3个字段)。awk将未定义的字段视为空字符串,"" < "Sun Oct 04 00:00:00 2022"永远为真,所以所有行都被输出。 - 字符串比较日期不可靠:直接比较日期字符串是按字符顺序判断的,无法正确处理月份、年份的逻辑先后关系,必须转换为Unix时间戳(从1970年开始的秒数)才能准确比较。
方案1:按指定日期筛选(匹配你的预期需求)
下面的命令会筛选出补丁日期早于Sun Oct 04 00:00:00 2022的行,同时处理数据中Marc的拼写错误(修正为Mar):
单行命令
awk -v dat="Sun Oct 04 00:00:00 2022" ' BEGIN { split("Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec", mon_list, " ") for(i=1; i<=12; i++) mon_map[mon_list[i]] = i split(dat, dat_parts, /[ :]/) dat_ts = mktime(dat_parts[7] " " mon_map[dat_parts[2]] " " dat_parts[3] " " dat_parts[4] " " dat_parts[5] " " dat_parts[6]) } match($0, /last patched on (.*)/, arr) { split(arr[1], parts, /[ :]/) if(parts[2] == "Marc") parts[2] = "Mar" patch_ts = mktime(parts[7] " " mon_map[parts[2]] " " parts[3] " " parts[4] " " parts[5] " " parts[6]) if(patch_ts < dat_ts) print $0 }' list.txt
逻辑说明
- 月份映射:把英文月份缩写转换成数字,方便
mktime函数解析。 - 指定日期转时间戳:将你输入的参考日期转换为Unix时间戳。
- 提取补丁日期:通过正则匹配
last patched on后的日期字符串,拆分后转成时间戳。 - 时间戳比较:补丁时间戳早于参考日期则输出该行。
方案2:自动筛选距今超过30天的行
如果不需要指定固定日期,而是自动计算当前时间往前推30天的阈值,可以用这个命令:
单行命令
awk ' BEGIN { split("Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec", mon_list, " ") for(i=1; i<=12; i++) mon_map[mon_list[i]] = i thirty_days_ago = systime() - 30*24*3600 } match($0, /last patched on (.*)/, arr) { split(arr[1], parts, /[ :]/) if(parts[2] == "Marc") parts[2] = "Mar" patch_ts = mktime(parts[7] " " mon_map[parts[2]] " " parts[3] " " parts[4] " " parts[5] " " parts[6]) if(patch_ts < thirty_days_ago) print $0 }' list.txt
逻辑说明
systime()获取当前Unix时间戳,减去30*24*3600(30天的秒数)得到30天前的时间戳阈值。- 后续逻辑和方案1一致,自动筛选符合条件的行。
内容的提问来源于stack exchange,提问作者Rame
相关产品推荐
相关产品推荐

