You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Bash从两种格式文件名中提取子串与版本号?

Bash提取文件名中的子串与版本号(适配两种格式)

针对你遇到的两种文件名格式:

example-substring-1.1.0.tgz
example-substring-1.1.0-branch-name.tgz

以下提供两种可靠的提取方案,最终可将子串(前缀)和版本号存入关联数组。

方案1:Bash参数展开(推荐,无需外部工具)

利用Bash内置的字符串处理能力,无需调用sed等外部命令,效率更高:

步骤分解

  1. 移除文件名的.tgz后缀:
    base=${filename%.tgz}
    
  2. 提取版本部分(包含分支名):
    通过匹配最后一个非数字字符后的连字符,截取后续所有内容(即从第一个数字开始的版本部分):
    version=${base##*[^0-9]-}
    
  3. 提取前缀(子串):
    从移除后缀的字符串中,去掉版本部分及其前面的连字符:
    prefix=${base%-${version}}
    
  4. 存入关联数组:
    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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 20:02:46