如何用Bash从两种格式文件名中提取子串与版本号?
Bash提取文件名中的子串与版本号(适配两种格式)
针对你遇到的两种文件名格式:
example-substring-1.1.0.tgz example-substring-1.1.0-branch-name.tgz
以下提供两种可靠的提取方案,最终可将子串(前缀)和版本号存入关联数组。
方案1:Bash参数展开(推荐,无需外部工具)
利用Bash内置的字符串处理能力,无需调用sed等外部命令,效率更高:
步骤分解
- 移除文件名的
.tgz后缀:base=${filename%.tgz} - 提取版本部分(包含分支名):
通过匹配最后一个非数字字符后的连字符,截取后续所有内容(即从第一个数字开始的版本部分):version=${base##*[^0-9]-} - 提取前缀(子串):
从移除后缀的字符串中,去掉版本部分及其前面的连字符:prefix=${base%-${version}} - 存入关联数组:
example_array["$prefix"]="$version"
测试验证
- 对
example-substring-1.1.0.tgz:prefix为example-substring,version为1.1.0 - 对
example-substring-1.1.0-branch-name.tgz:prefix为example-substring,version为1.1.0-branch-name
方案2:改进版sed命令
如果偏好使用sed,可通过正则匹配版本的起始特征(数字开头)来适配两种格式:
提取命令
read raw_prefix version <<< $(echo "$filename" | sed -E 's/^(.+-)([0-9].*)\.tgz$/\1 \2/') prefix=${raw_prefix%-} # 移除前缀结尾的多余连字符
存入关联数组
example_array["$prefix"]="$version"
完整脚本示例
#!/bin/bash declare -A example_array # 待处理文件列表 files=( "example-substring-1.1.0.tgz" "example-substring-1.1.0-branch-name.tgz" "foo-bar-baz-2.3.4.tgz" "foo-bar-baz-2.3.4-test-branch.tgz" ) for filename in "${files[@]}"; do # 使用方案1的参数展开方法 base=${filename%.tgz} version=${base##*[^0-9]-} prefix=${base%-${version}} example_array["$prefix"]="$version" done # 打印结果 for key in "${!example_array[@]}"; do echo "example_array[\"$key\"]=\"${example_array[$key]}\"" done
运行输出
example_array["example-substring"]="1.1.0-branch-name" example_array["foo-bar-baz"]="2.3.4-test-branch"
注意:Bash关联数组的键具有唯一性,若存在相同前缀的文件,后处理的条目会覆盖之前的。若需保留所有条目,可改用索引数组或给键添加唯一标识。
内容的提问来源于stack exchange,提问作者cybersnow1989
相关产品推荐
相关产品推荐

