如何从日志文件提取type1/type2的无重复版本号(附现有脚本)
提取日志文件中type1/type2的唯一版本号脚本实现
需求背景
现有main.log文件包含以下文件名列表:
admin-dev.log admin-prod.log type1-app-dev-1.24.2.log type1-app-dev-latest.log type1-app-prod-1.24.2.log type1-app-prod-1.24.3.log type1-app-prod-latest.log type2-app-stage-1.24.2.log type2-app-dev-1.38.6.log type2-app-dev-latest.log type2-app-prod-1.38.6.log type2-app-prod-1.38.7.log type2-app-prod-latest.log
需要从中提取type1或type2对应的版本号并去除重复版本,预期输出为:
type1: 1.24.2 type1: 1.24.3 type1: latest type2: 1.38.6 type2: 1.38.7 type2: latest
原脚本存在的问题
你提供的脚本存在以下几个问题:
- 替换规则错误:脚本中用
.apk作为后缀匹配,但实际文件后缀是.log,导致无法正确提取版本号 - 未做去重处理:会输出重复的版本条目
- 无效判断:
if [ "$line" != "$file_list" ];完全多余,file_list是文件名,日志里不存在该内容 - 逻辑漏洞:非
type1/type2的行(比如admin开头的行)会输出type2:空内容
正确实现方案
方案1:使用awk(推荐,简洁高效)
awk适合处理这类文本提取和去重需求,一行命令即可完成:
awk '/type[12]-app/ { split($0, arr, /-app-|\.log/) type = substr($0, 1, 5) ver = arr[2] if (!seen[type,ver]++) { printf("%s: %s\n", type, ver) } }' main.log | sort
逻辑说明:
- 只匹配包含
type1-app或type2-app的行 - 用
-app-和.log作为分隔符拆分每行内容,提取版本号部分 - 提取
type1或type2前缀 - 用
seen[type,ver]数组记录已输出的组合,实现去重 - 最后排序保证输出顺序和预期一致
方案2:改进Shell脚本
如果坚持用shell循环处理,可修改为以下版本:
#!/bin/bash file_list="main.log" # 用关联数组去重 declare -A seen while IFS= read -r line; do # 匹配type1或type2的行 if [[ $line =~ ^type([12])-app-.+\.log$ ]]; then type="type${BASH_REMATCH[1]}" # 提取版本号:去掉开头的typeX-app-和结尾的.log ver=$(echo "$line" | sed -E 's/^type[12]-app-(.+)\.log/\1/') # 去重判断 if [[ -z ${seen["$type:$ver"]} ]]; then echo "$type: $ver" seen["$type:$ver"]=1 fi fi done < "$file_list" | sort
逻辑说明:
- 用正则匹配只处理
type1/type2开头的有效行 - 通过正则捕获组获取type标识
- 用sed正确提取版本号
- 用关联数组
seen记录已输出的type:ver组合,避免重复 - 最后排序保证输出有序
测试验证
运行上述任意方案,输出结果与预期完全一致,且自动去除了重复版本(比如type1:1.24.2在dev和prod中都出现,但只输出一次)。
内容的提问来源于stack exchange,提问作者Sasha Milic
相关产品推荐
相关产品推荐

